No registration for type ICommandHandler using SimpleInjector APIv3

后端 未结 1 844
佛祖请我去吃肉
佛祖请我去吃肉 2021-01-25 04:07

I\'ve been playing around with SimpleInjector and I\'m trying to register properly all command handlers.

Here is my code:

CQRS.cs

public interf         


        
相关标签:
1条回答
  • 2021-01-25 04:22

    The Simple Injector API clearly separates between registrations for collections and one-to-one mappings. In your composition root, you are making the following registration:

    container.RegisterCollection(typeof(ICommandHandler<>), 
        new[] { typeof(ICommandHandler<>).Assembly });
    

    The API Documentation for RegisterCollection states:

    Registers a collection of serviceTypes, whose instances will be resolved lazily each time the resolved collection of serviceType is enumerated. The underlying collection is a stream that will return individual instances based on their specific registered lifestyle, for each call to IEnumerator<T>.Current. The order in which the types appear in the collection is the exact same order that the items were registered, i.e the resolved collection is deterministic.

    In other words, you are allowing command handlers to be resolved as collections, by requesting IEnumerable<ICommandHandler<T>>.

    In your CommandDispatcher however, you request a single ICommandHandler<T> by calling container.GetInstance(handlerType). Since there is no one-to-one mapping for an ICommandHandler<T>, Simple Injector informs you about this by throwing:

    No registration for type ICommandHandler<CreateUser> could be found. There is, however, a registration for IEnumerable<ICommandHandler<CreateUser>>; Did you mean to call GetAllInstances<ICommandHandler<CreateUser>>() or depend on IEnumerable<ICommandHandler<CreateUser>>?

    To fix this, there are two options:

    1. Either you register your handlers using the one-to-one mapping, or
    2. You resolve a collection of handlers within your CommandDispatcher by calling GetAllInstances(Type).

    Since there will always be a one-to-one mapping between a command and its handler (meaning: there will be exactly one handler per command), option 1 is the most obvious solution. So change your registration to the following:

    // Use 'Register' instead of 'RegisterCollection'.
    container.Register(typeof(ICommandHandler<>), 
        new[] { typeof(ICommandHandler<>).Assembly });
    
    0 讨论(0)
提交回复
热议问题