Simple Injector usage for generic command handler

后端 未结 1 2013
温柔的废话
温柔的废话 2021-02-09 05:04

The interfaces,commands and command handler set up as per instructions in Simpleinjector wiki.

public interface ICommand
{
    string Name { get; set; }
}

publi         


        
1条回答
  •  萌比男神i
    2021-02-09 05:21

    Your commands (Command1 and Command2) are not services: they should not be registered. They are runtime data (message) that you pass through your services (your command handlers). So you should remove the Collection.Register (RegisterAll in v2) registration. It is of no use. You already see its of no use, since in your example you are newing the Command2 up manually, which is the right thing to do.

    What you are doing in the last three lines of code is dispatching a command of an unknown type to the right command handler registration. You always need some reflection to pull this of, since you need to build the closed ICommandHandler type based on the command type, which is something you don't know at compile time. Instead of using the C# dynamic keyword, you can also use the .NET reflection API, but in my experience using dynamic is better in this particular case. One important downside of the reflection API is that the API will always wrap any thrown exception (in case of a failure) with an InvocationException and that makes it harder to do certain exception handling up the call stack.

    So long story short, this should be your registration:

    Container container = new Container();
    
    container.Register(
        typeof(ICommandHandler<>),
        typeof(ICommandHandler<>).Assembly);
    
    container.RegisterDecorator(
        typeof(ICommandHandler<>), 
        typeof(CommandDecorator<>));
    

    And this should be the dispatching logic:

    var type = typeof(ICommandHandler<>).MakeGenericType(command.GetType());
    
    dynamic handler = container.GetInstance(type);
    handler.Execute((dynamic)command);
    

    0 讨论(0)
提交回复
热议问题