Add a set of builder APIs that can handle shared state and creation
- Dominant language
- C#
- Stars
- 4.6k
- Forks
- 605
- PR merge metrics
- No merged PRs in 30d
Description
# Overview
Currently, there are a number of static APIs on each package type to enable creating based off of different sources. However, this has a couple of problems:
- Makes a lot of code duplication to enable any new open related APIs
- No easy way to create without knowing the package type (for scenarios where we just need a package)
- Any initialization has to be duplicated and is not passed on to methods such as `Clone()`
## Proposal
Expose a builder pattern with something like this that builds a middleware pipeline to construct the package:
```csharp
public interface IPackageBuilder
where TPackage : OpenXmlPackage
{
///
/// Create an instance of the package.
///
/// A instance.
TPackage Create();
///
/// Gets a key/value collection that can be used to share data between middleware.
///
IDictionary Properties { get; }
///
/// Add middleware to the package builder.
///
/// The middleware to add.
/// The .
IPackageBuilder Use(Func, PackageInitializerDelegate> configure);
///
/// Create a copy of the builder that will be independent of the original, but retains the existing middleware and properties.
///
/// A new .
IPackageBuilder Clone();
///
/// Builds the pipeline to initialize the package. Additional calls to this will return the cached pipeline unless
/// more middleware has been added.
///
/// The pipeline to initialize a package.
PackageInitializerDelegate Build();
}
```
This can enable something like the following:
```csharp
var factory = WordprocessingDocument.CreateBuilder()
.Use((package, next) => next(package))
.UseSomeCommonBehavior()
.Build();
using var package = factory.Open(stream);
```
This sets up a factory that will produce a package based on the supplied middleware, which can contain shared state, etc that is needed in each package. It also sets up things like Clone to use this as well so all packages are set up in a consistent way.
An initial implementation is available here: https://github.com/dotnet/Open-XML-SDK/pull/1474
Contributor guide
Research direction
Start by reviewing the initial implementation in pull request 1474 and the existing static creation APIs on each package type. Compare the proposal's IPackageBuilder, middleware, shared Properties, Build, Clone, and factory creation requirements with that implementation; done means the agreed builder behavior is defined and consistently supports package creation and cloning.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp
- Domain
- backend-api-design
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 25/100