Simple Composite injection registration combining open and closed shared implementations
I'm working on creating authentication wizards for my teams, but I'm having problems registering types with a DI container with a simple injector.
The point is as follows:
- I have a (currently) the only validator that should always be applied
DataAnnotationsCommandValidator<TCommand>
. - I also have a few validators that need to be applied to specific commands. Example:
CreateRefreshTokenCommandValidator
that implementsICommandValidator<CreateRefreshTokenCommand>
.
According to Simple Injection Documentation , should be created CompositeCommandValidator
in such cases. I mimicked the implementation mentioned in the documentation, which means mine ValidationCommandHandlerDecorator
may still have a dependency on ICommandValidator<TCommand>
instead IEnumerable
.
Then there is the Simple Injector container configuration. My configuration looks like this:
_container.RegisterManyForOpenGeneric(
typeof(ICommandValidator<>),
_container.RegisterAll,
typeof (ICommandValidator<>).Assembly);
_container.RegisterAllOpenGeneric(
typeof(ICommandValidator<>),
typeof(DataAnnotationsCommandValidator<>));
_container.RegisterSingleOpenGeneric(
typeof(ICommandValidator<>),
typeof(CompositeCommandValidator<>));
However, when I debug the application, CompositeCommandValidator
only certain validators are injected into (I'm missing DataAnnotationsCommandValidator
). I have tried several different configurations but to no avail. How do I set up a simple injector for the correct behavior?
source to share
The method RegisterManyForOpenGeneric
will only check assemblies for non-evolutionary implementations of the given interface, because open source implementations often require special attention. There are two options here.
Option 1:
var types = OpenGenericBatchRegistrationExtensions.GetTypesToRegister(
_container,
typeof (ICommandValidator<>),
AccessibilityOption.PublicTypesOnly,
typeof (ICommandValidator<>).Assembly)
.ToList();
types.Add(typeof(DataAnnotationsValidator<>));
_container.RegisterAll(typeof(ICommandValidator<>), types);
Here we use a method GetTypesToRegister
to find all non-common implementations, add an open common type to this collection, and register the entire set with RegisterAll
.
The second option is to mix RegisterManyForOpenGeneric
with AppendToCollection
:
_container.RegisterManyForOpenGeneric(typeof(ICommandValidator<>),
_container.RegisterAll,
typeof(ICommandValidator<>).Assembly);
// using SimpleInjector.Advanced;
_container.AppendToCollection(typeof(ICommandValidator<>),
typeof(DataAnnotationsValidator<>));
source to share