Castle Windsor - 如何在具有泛型的类中注册实现具有泛型的接口的接口?

时间:2014-06-06 14:39:56

标签: c# generics inversion-of-control castle-windsor decorator

根据下面的代码,如何在Castle Windsor(最新版本)中设置注册以使ISomeService解析为SomeDecorator< SomeRequest,SomeResponse>?

public interface IService<in TRequest, out TResponse>
{
    TResponse Get(TRequest request);
}

public class SomeRequest
{
    public int SomeId { get; set; }
    public int SomeOtherId { get; set; }
}

public class SomeResponse
{
    public int SomeId { get; set; }
    public string SomeName { get; set; }
    public IEnumerable<string> SomeList { get; set; }
}

public interface ISomeService : IService<SomeRequest, SomeResponse> { }

public class SomeService : ISomeService
{
    public SomeResponse Get(SomeRequest request)
    {
        return new SomeResponse { SomeId = request.SomeId, SomeName = "The Name", SomeList = new List<string>() };
    }
}

public class SomeDecorator<TRequest, TResponse> : IService<TRequest, TResponse>
{
    private readonly IService<TRequest, TResponse> _service;

    public SomeDecorator(IService<TRequest, TResponse> service)
    {
        _service = service;
    }

    public TResponse Get(TRequest request)
    {
        //Do something before
        var response = _service.Get(request);
        //Do something after
        return response;
    }
}

通过以下注册,ISomeService正在解析SomeService,而不是SomeDecorator &LT; SomeRequest,SomeResponse&gt;

public void Install(IWindsorContainer container, IConfigurationStore store)
{
    container.Register(Component
        .For(IService<SomeRequest,SomeResponse>)
        .ImplementedBy(ISomeService));
    container.Register(Component
        .For(ISomeService)
        .ImplementedBy(SomeService));
    container.Register(Component
        .For(IService<,>)
        .ImplementedBy(SomeDecorator<,>)
        .IsDefault());
}

当我尝试注册由SomeDecorator实现的ISomeService时&lt; SomeRequest,SomeResponse&gt;,我收到以下错误消息:

  

无法投射类型为#Some; SomeDecorator`2 [SomeRequest,SomeResponse]&#39;输入&#39; ISomeService&#39;。

1 个答案:

答案 0 :(得分:0)

这是让它运转的一种方法。此解决方案的缺点是您必须针对要装饰的每个类注册装饰器。

正如我在上面的评论中所说,您可以通过删除ISomeService并使用public class SomeService : IService<SomeRequest, SomeResponse>来简化您的设计。然后装饰器的注册如下:

container.Register(
    Component.For<IService<SomeRequest, SomeResponse>>()
        .ImplementedBy<SomeDecorator<SomeRequest, SomeResponse>>(),
    Component.For<IService<SomeRequest, SomeResponse>>()
        .ImplementedBy<SomeService>());

另请注意,您可以使用LINQ查询自动注册所有通用实现。

相关问题