简体   繁体   English

温莎城堡-如何将实现泛型接口的接口注册到具有泛型的类?

[英]Castle Windsor - How can I register an interface that implements an interface with generics to a class with generics?

Given the code below, How do I set up the registrations in Castle Windsor (latest version) to make ISomeService resolve to SomeDecorator< SomeRequest, SomeResponse>? 给定以下代码,如何在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;
    }
}

With the following registrations, ISomeService is resolving to SomeService, not SomeDecorator < SomeRequest, SomeResponse> 通过以下注册,ISomeService解析为SomeService,而不是SomeDecorator <SomeRequest,SomeResponse>

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

When I try to register ISomeService to be implemented by SomeDecorator< SomeRequest, SomeResponse>, I get the following error message: 当我尝试注册由SomeDecorator <SomeRequest,SomeResponse>实现的ISomeService时,出现以下错误消息:

Unable to cast object of type 'SomeDecorator`2[SomeRequest,SomeResponse]' to type 'ISomeService'. 无法将类型为'SomeDecorator`2 [SomeRequest,SomeResponse]'的对象强制转换为类型为'ISomeService'的对象。

Here's one way to get it working. 这是使其工作的一种方法。 The downside of this solution is that you have to register the decorator against each class you want to decorate. 该解决方案的缺点是,您必须针对要装饰的每个类注册装饰器。

As I said in my comment above you can simplify your design by getting rid of ISomeService and go with public class SomeService : IService<SomeRequest, SomeResponse> instead. 正如我在上面的评论中所说,您可以通过摆脱ISomeService并使用public class SomeService : IService<SomeRequest, SomeResponse>来简化设计public class SomeService : IService<SomeRequest, SomeResponse> The registration for the decorator then looks like this: 装饰器的注册如下所示:

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

Also note you could automate the registration of all your generic implementations with LINQ queries. 还要注意,您可以使用LINQ查询自动注册所有通用实现。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM