Dependency injection 为你的国际奥委会准备一个包装是个好主意吗?

Dependency injection 为你的国际奥委会准备一个包装是个好主意吗?,dependency-injection,structuremap,ioc-container,wrapper,abstraction,Dependency Injection,Structuremap,Ioc Container,Wrapper,Abstraction,我已经使用StructureMap一年多了。一直以来,我都有一个名为IoC的包装类,看起来像这样 class IoC { public static T GetInstance<T>() { return (T)GetInstance(typeof(T)); } public static IEnumerable<T> GetAllInstances<T>() { return Objec

我已经使用StructureMap一年多了。一直以来,我都有一个名为IoC的包装类,看起来像这样

class IoC {
    public static T GetInstance<T>()
    {
        return (T)GetInstance(typeof(T));
    }
    public static IEnumerable<T> GetAllInstances<T>()
    {
        return ObjectFactory.GetAllInstances<T>();
    }

    public static IEnumerable GetAllInstances(Type type)
    {
        return ObjectFactory.GetAllInstances(type);
    }

    public static object GetInstance(Type type)
    {
        return ObjectFactory.GetInstance(type);
    }

    public static void Inject<T>(T obj)
    {
        ObjectFactory.Inject(obj);
    }
}
class-IoC{
公共静态GetInstance()
{
返回(T)GetInstance(typeof(T));
}
公共静态IEnumerable GetAllInstances()
{
返回ObjectFactory.GetAllInstances();
}
公共静态IEnumerable GetAllInstances(类型)
{
返回ObjectFactory.GetAllInstances(类型);
}
公共静态对象GetInstance(类型)
{
返回ObjectFactory.GetInstance(类型);
}
公共静态无效注入(T obj)
{
ObjectFactory.Inject(obj);
}
}
我添加了包装器,假设我可能希望在接下来的某个时候更改IoC容器。在这一点上,我认为这是不好的。一个原因是:我不能在代码中使用ObjectFactory来做其他有趣的事情,我必须使用这个包装器。另一件事是:我们的代码不应该真正独立于DependencyInjection容器


使用这种方法的优点/缺点是什么?

优点是您可以轻松地交换IOC容器。缺点是您会丢失IOC容器特有的任何功能。MVC turbine使用这种方法。看看它的源代码,看看它是如何处理定位器的

基于这个原因,该项目已经开发出来。它是对DI框架的抽象,它定义了一个非常类似于
IoC
类的接口。我甚至开发了图书馆;直接实现公共服务定位器接口的DI库

因此,从这个意义上讲,对DI框架进行抽象并不奇怪。但是,当正确地(完全地)执行依赖项注入时,我们的想法是相应地调整应用程序的设计,在应用程序根目录中配置容器,并且最好在应用程序中只有一个位置来组装类型(读取:were
GetInstance
is called)。对于ASP.NET MVC应用程序,这将是
ControllerFactory
。对于ASP.NET WebForms应用程序,通常需要重写一个

当您遵循这些规则时,没有理由使用这样的抽象,因为您只是在应用程序中的单个位置调用容器。但是,如果这对您来说不可行,那么使用或您自己的抽象是一种选择

但是,在决定让代码依赖于IoC库的抽象之前,请后退一步,因为这通常会导致很多问题。从代码中回调容器:

  • 使代码更难测试
  • 隐藏依赖项,使代码更难阅读和维护
  • 禁用编译时支持
  • 不允许使用工具验证依赖关系图

如果你有很多库和在这些库之上构建的很多应用程序,那么你最终会得到大量的IoC注册码,这些注册码会在所有这些应用程序中重复


您可以让每个库负责向容器注册自己,但它必须了解特定的IoC实现。或者,您可以按照您的建议创建一个IoC包装器,并让您的库负责通过IoC包装器进行注册。

围绕外部依赖项使用包装器是有意义的,但是,我不知道是否有任何真实的情况下人们会切换IoC容器。将这种包装称为“合格容器”。他最近写了一篇文章,他明确地称之为反模式。