【问题标题】:Dependency Injection coupled with a Generic依赖注入与泛型相结合
【发布时间】:2015-01-12 03:32:18
【问题描述】:

我已经非常熟悉 依赖注入 和松散耦合组件的强大功能。当我出于教育目的试图增强或建立它时,我偶然发现了一个问题:

public interface IReader<TParameter, TOutput>
{
     TOutput Read(TParameter parameter);
}

public class Customer : IReader<int, CustomerModel>
{
     public CustomerModel Read(int parameter)
     {      
          // Implementation...
     }
}

当您尝试使用依赖注入时,问题就来了。我尝试过:

public class Reader<TParameter, TOutput>
{
     private IReader<TParameter, TOutput> reader;
     public Reader(IReader<TParameter, TOutput> reader)
     {
          // Link through Constructor... 
     }
}

这行不通,但是在这个阶段,当涉及到泛型时,如何实现和执行依赖注入?有可能吗?

【问题讨论】:

  • 您使用的是哪个 IoC 容器?我知道对于 Unity,您应该能够使用 container.RegisterType&lt;IReader&lt;TParameter, TOutput&gt;, Customer&gt;() 其他框架可能会受到更多限制。
  • @Jarga 目前没有,想先尝试没有 IoC 框架的简单前提。
  • 看看这个链接是否回答了你的问题:stackoverflow.com/questions/700966/generic-type-in-constructor [1]:
  • 我在上面的评论中犯了一个错误,你需要在 Unity 中做container.RegisterType&lt;IReader&lt;int, CustomerModel&gt;, Customer&gt;()。无论哪种方式,如果您自己滚动,那么您应该能够像匹配其他接口类型一样匹配 typeIReader&lt;int, CustomerModel&gt;
  • 对不起,我真的想在这里理解问题。首先,重命名类可能会有所帮助。实现了IReader的客户,以及依赖于IReader但没有实现的Reader?!我建议将 Customer 重命名为 CustomerReader (它真的是在读取客户对象,还是只是在给定整数的情况下创建模型?)当你说“这不起作用”时,你遇到这些类的问题是什么?

标签: c# asp.net-mvc generics dependency-injection


【解决方案1】:

我同意一些 cmets 的观点,即如果没有 IOC 框架或相当多的自定义反射,对于这种情况的泛型,您不会从 DI 中获得太多收益。您描述的模式似乎是代理模式,其中包含封装接口的最后一个 Reader 类。

为了清楚起见,通过重命名最后一个类ReaderProxy,我试图让您的代码更进一步,希望展示如何在没有框架或通用对象的自定义初始化的情况下执行依赖注入,从而简化实际初始化行。

下面的代码将展示如何使用依赖注入(参见小提琴:https://dotnetfiddle.net/cfNCyl)。

var reader = new ReaderProxy<int, CustomerModel>(new Customer());
var model = reader.Read(5);
Console.WriteLine(model.Id);

以下是上述代码所需的类和接口(包括一个简单的CustomerModel):

public interface IReader<TParameter, TOutput>
{
     TOutput Read(TParameter parameter);
}

public class Customer : IReader<int, CustomerModel>
{
     public CustomerModel Read(int parameter)
     {      
         return new CustomerModel() { Id = parameter };
     }
}

public class CustomerModel
{
    public int Id { get; set; }
}

public class ReaderProxy<TParameter, TOutput>
    : IReader<TParameter, TOutput>
{
    private IReader<TParameter, TOutput> reader;
    public ReaderProxy(IReader<TParameter, TOutput> reader)
    {
          this.reader = reader;
    }
    public TOutput Read(TParameter parameter)
    {
        return this.reader.Read(parameter);
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-06
    相关资源
    最近更新 更多