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 implements ICommandValidator<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?

+3


source to share


1 answer


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<>));

      

+2


source







All Articles