Skip to content

Commit a925836

Browse files
authored
Add enumeration to IFeatureCollection (#1452)
This will allow us to copy or inspect features from one collection to another
1 parent 3ed3d3a commit a925836

File tree

31 files changed

+634
-1918
lines changed

31 files changed

+634
-1918
lines changed

.editorconfig

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,3 +68,87 @@ dotnet_diagnostic.CA1065.severity = suggestion
6868

6969
# CA1054: URI-like parameters should not be strings
7070
dotnet_diagnostic.CA1054.severity = suggestion
71+
csharp_using_directive_placement = outside_namespace:silent
72+
csharp_prefer_simple_using_statement = true:suggestion
73+
csharp_prefer_braces = true:silent
74+
csharp_style_namespace_declarations = block_scoped:silent
75+
csharp_style_prefer_method_group_conversion = true:silent
76+
csharp_style_prefer_top_level_statements = true:silent
77+
csharp_style_expression_bodied_methods = false:silent
78+
csharp_style_expression_bodied_constructors = false:silent
79+
csharp_style_expression_bodied_operators = false:silent
80+
csharp_style_expression_bodied_properties = true:silent
81+
csharp_style_expression_bodied_indexers = true:silent
82+
csharp_style_expression_bodied_accessors = true:silent
83+
csharp_style_expression_bodied_lambdas = true:silent
84+
csharp_style_expression_bodied_local_functions = false:silent
85+
csharp_indent_labels = one_less_than_current
86+
csharp_style_throw_expression = true:suggestion
87+
88+
[*.{cs,vb}]
89+
#### Naming styles ####
90+
91+
# Naming rules
92+
93+
dotnet_naming_rule.interface_should_be_begins_with_i.severity = suggestion
94+
dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface
95+
dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i
96+
97+
dotnet_naming_rule.types_should_be_pascal_case.severity = suggestion
98+
dotnet_naming_rule.types_should_be_pascal_case.symbols = types
99+
dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case
100+
101+
dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = suggestion
102+
dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members
103+
dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case
104+
105+
# Symbol specifications
106+
107+
dotnet_naming_symbols.interface.applicable_kinds = interface
108+
dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
109+
dotnet_naming_symbols.interface.required_modifiers =
110+
111+
dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum
112+
dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
113+
dotnet_naming_symbols.types.required_modifiers =
114+
115+
dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method
116+
dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
117+
dotnet_naming_symbols.non_field_members.required_modifiers =
118+
119+
# Naming styles
120+
121+
dotnet_naming_style.begins_with_i.required_prefix = I
122+
dotnet_naming_style.begins_with_i.required_suffix =
123+
dotnet_naming_style.begins_with_i.word_separator =
124+
dotnet_naming_style.begins_with_i.capitalization = pascal_case
125+
126+
dotnet_naming_style.pascal_case.required_prefix =
127+
dotnet_naming_style.pascal_case.required_suffix =
128+
dotnet_naming_style.pascal_case.word_separator =
129+
dotnet_naming_style.pascal_case.capitalization = pascal_case
130+
131+
dotnet_naming_style.pascal_case.required_prefix =
132+
dotnet_naming_style.pascal_case.required_suffix =
133+
dotnet_naming_style.pascal_case.word_separator =
134+
dotnet_naming_style.pascal_case.capitalization = pascal_case
135+
dotnet_style_coalesce_expression = true:suggestion
136+
dotnet_style_null_propagation = true:suggestion
137+
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion
138+
dotnet_style_prefer_auto_properties = true:warning
139+
dotnet_style_object_initializer = true:suggestion
140+
dotnet_style_collection_initializer = true:suggestion
141+
dotnet_style_prefer_simplified_boolean_expressions = true:suggestion
142+
dotnet_style_prefer_conditional_expression_over_assignment = true:silent
143+
dotnet_style_prefer_conditional_expression_over_return = true:suggestion
144+
dotnet_style_explicit_tuple_names = true:suggestion
145+
dotnet_style_prefer_inferred_tuple_names = true:suggestion
146+
dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
147+
dotnet_style_prefer_compound_assignment = true:suggestion
148+
dotnet_style_prefer_simplified_interpolation = true:suggestion
149+
dotnet_style_namespace_match_folder = true:suggestion
150+
dotnet_style_operator_placement_when_wrapping = beginning_of_line
151+
tab_width = 4
152+
indent_size = 4
153+
end_of_line = crlf
154+
dotnet_diagnostic.CA1043.severity = suggestion

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
99
### Added
1010
- Packages can now be saved on .NET Core and .NET 5+ if constructed with a path or stream (#1307).
1111
- Packages can now support malformed URIs (such as relationships with a URI such as `mailto:person@`)
12+
- `IFeatureCollection` can now be enumerated and has a helpful debug view to see what features are registered (#1452)
1213

1314
### Changed
1415
- When validation finds incorrect part, it will now include the relationship type rather than a class name

Directory.Packages.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
<PackageVersion Include="NuGet.Packaging.Core" Version="6.4.0" />
1818
<PackageVersion Include="NuGet.Protocol" Version="6.4.0" />
1919
<PackageVersion Include="NuGet.Resolver" Version="6.4.0" />
20-
<PackageVersion Include="StyleCop.Analyzers" Version="1.2.0-beta.321" />
20+
<PackageVersion Include="StyleCop.Analyzers" Version="1.2.0-beta.507" />
2121
<PackageVersion Include="Svg" Version="3.4.4" />
2222
<PackageVersion Include="System.CodeDom" Version="7.0.0" />
2323
<PackageVersion Include="System.Collections.Immutable" Version="5.0.0" />

docs/Features.md

Lines changed: 26 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,33 @@
22

33
Features are a new concept in v2.14 and later that allows for behavior and state to be contained within the document or part. This is accessed via `Features` property on packages, parts, and elements. Elements inherit part features, and parts inherit package features.
44

5-
This is inspired by the pattern ASP.NET Core uses to modify behavior of HttpContext: https://learn.microsoft.com/aspnet/core/fundamentals/request-features
5+
This is inspired by the pattern ASP.NET Core uses to modify behavior of HttpContext: https://learn.microsoft.com/aspnet/core/fundamentals/request-features. This is an implementation of the [strategy pattern](https://refactoring.guru/design-patterns/strategy) that makes it easy to replace behavior on the fly.
6+
7+
As of v3.0, the `IFeatureCollection` includes the ability to enumerate registered features.
8+
9+
## Visualizing Registered Features
10+
11+
The in-box implementations of the `IFeatureCollection` provide a helpful debug view so you can see what features are available and what their properties/fields are:
12+
13+
![Features Debug View](feature-debug-view.png)
614

715
## Current Features
816

9-
The features that are currently available are described below and at what scope they are available. This is important, because and element by itself will not have any features available, while an element in one part may have different features than another part.
17+
The features that are currently available are described below and at what scope they are available:
18+
19+
### IDisposableFeature
20+
21+
This feature allows for registering actions that need to run when a package or a part is destroyed or disposed:
22+
23+
```csharp
24+
OpenXmlPackage package = GetSomePackage();
25+
package.Features.Get<IDisposableFeature>().Register(() => /* Some action that is called when the package is disposed */);
26+
27+
OpenXmlPart part = GetSomePart();
28+
part.Features.Get<IDisposableFeature>().Register(() => /* Some action that is called when the part is removed or closed */);
29+
```
30+
31+
Packages and parts will have their own implementations of this feature. Elements will retrieve the feature for their containing part if available.
1032

1133
### IPackageEventsFeature
1234

@@ -51,28 +73,10 @@ Generally, assume that there may be a singleton implementation for the events an
5173

5274
> Note: There may be times when the part root is changed but an event is not fired. Not all areas have been identified where it would make sense to raise an event. Please file an issue if you find one.
5375
54-
## DocumentFormat.OpenXml.Features - unreleased
76+
## DocumentFormat.OpenXml.Features
5577

5678
This library contains additional (non-core) features that build on top of built-in features and functionality.
5779

58-
### IDisposableFeature
59-
60-
This feature allows for registering features that need to be disposed at the same time as the feature goes out of scope. This allows a feature to be created, but its lifetime managed concurrently with the collection it is added to. The recommended way to use it is simply to call the following method:
61-
62-
```csharp
63-
OpenXmlPackage package = GetSomePackage();
64-
package.TryAddDisposableFeature();
65-
66-
OpenXmlPart part = GetSomePart();
67-
part.SetDisposable(new ExampleFeature());
68-
69-
public class ExampleFeature : IDisposable
70-
{
71-
}
72-
```
73-
74-
This will add `ExampleFeature` to the part feature, and register it to be disposed when the part is disposed.
75-
7680
### IRandomNumberGeneratorFeature
7781
This feature allows for a shared service to generate random numbers and fill an array.
7882

@@ -121,7 +125,7 @@ Assert.NotEqual(p1.ParagraphId, p2.ParagraphId);
121125
Assert.Equal(2, shared.Count);
122126
```
123127

124-
## DocumentFormat.OpenXml.Linq - unreleased
128+
## DocumentFormat.OpenXml.Linq
125129

126130
### IPartRootXElementFeature
127131

docs/feature-debug-view.png

58.3 KB
Loading

0 commit comments

Comments
 (0)