Customizing Autofac's component resolution / Issue with generic co-/contravariance

后端 未结 3 875
小蘑菇
小蘑菇 2020-12-25 14:17

First, sorry for the vague question title. I couldn\'t come up with a more precise one.

Given these types:

                                                  


        
3条回答
  •  没有蜡笔的小新
    2020-12-25 14:46

    What you are asking is not possible without own coding. Basically, you are asking the following: If the type I tried to resolve isn't found, return another type that can be converted to it, e.g. if you try to resolve IEnumerable return a type that is registered for ICollection. This is not supported. One simple solution would be the following: Register FooCommandHandler as a handler for ICommandHandler. For this to work, ICommandHandler needs to be contravariant:

    interface ICommand { }
    
    class FooCommand : ICommand { }
    
    class SpecialFooCommand : FooCommand { }
    
    interface ICommandHandler where T : ICommand
    {
        void Handle(T command);
    }
    
    class FooCommandHandler : ICommandHandler
    {
        public void Handle(FooCommand command)
        {
            // ...
        }
    }
    
    var builder = new ContainerBuilder();
    builder.RegisterType()
           .As>()
           .As>();
    var container = builder.Build();
    var fooCommand = new FooCommand();
    var specialCommand = new SpecialFooCommand();
    container.Resolve>().Handle(fooCommand);
    container.Resolve>().Handle(specialCommand);
    container.Resolve>().Handle(specialCommand);
    

    BTW: The way you are using the container, you apply the Service locator anti-pattern. This should be avoided.

提交回复
热议问题