在一个非通用定位器中找到不同的通用服务

时间:2016-12-07 19:27:41

标签: c# generics design-patterns service

我有各种实现

的服务
public interface IReceiver<PayLoad>
{
    string Name {get;}
    Task SendObjectContainerAsync(ObjectContainer<PayLoad> m);
    Task<ObjectContainer<PayLoad>> GetSnapshot();
}

例如

public class Printer : IReceiver<TextDocument>

public class TextDocumentService : IReceiver<Letter>

现在我想在一个Controller中收集每个IReceiver的所有实例,我可以

public class Broker<Payload>
{
     List<IReceiver<Payload>> receivers;         
}

并为每种类型的IReceiver初始化一个实例,然后将其DI引入IReceivers,以使它们能够从其他地方注册并获取实例。

这是处理不同服务的好方法吗?我认为它对许多经纪人来说有点混乱,我宁愿有类似

的东西
static void register<Payload>(IReceiver<Payload> RegisterMe)

static List<IReceiver<Payload>> getReceivers<PayLoad>()

但我无法实现此Locator,因为我不知道如何在一个非泛型类中管理不同的通用列表

任何建议?

1 个答案:

答案 0 :(得分:0)

使用依赖注入框架,您应该能够配置哪些接收器要特定注入到特定的Broker<PayLoad>实例中。

另一方面,你应该练习构造函数注入

public class Broker<Payload>
{
     public Broker(IList<IReceiver<PayLoad>> receivers)
     {
          Receivers = receivers;
     }

     public IList<IReceiver<PayLoad>> { get; }
}

现在,下一个问题是您希望代理处理多个接收器类型。因此,最简单的方法是在IReceiver<PayLoad>界面上使用小型重构:

// No more PayLoad generic type parameter! Let's move it to
// the methods
public interface IReceiver
{
    string Name { get; }
    Task SendObjectContainerAsync<TPayLoad>(ObjectContainer<TPayLoad> m);
    Task<ObjectContainer<TPayLoad>> GetSnapshot<TPayLoad>();
}

最后,您的经纪人将看起来如下:

public class Broker
{
     public Broker(IList<IReceiver> receivers)
     {
          Receivers = receivers;
     }

     public IList<IReceiver> { get; }
}

关于Locator事物

您打算实施静态服务定位器吗?不要这样做,它被认为是一种反模式,因为你要将你的组件耦合到他们如何接收他们的依赖,而你应该避免这种情况。 / p>

组件应该保持不知道如何获得它们的依赖关系,因为这是更高层的可重用性,通常是IoC / DI容器。

此外,它使您的代码更适合测试,因为您可以在不集成IoC / DI容器的情况下测试组件,因为您只需要构造函数参数。