为您的 IoC 包装一个好主意吗? [英] Is having a wrapper for your IoC a good idea?

查看:31
本文介绍了为您的 IoC 包装一个好主意吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

class IoC {public static T GetInstance(){返回 (T)GetInstance(typeof(T));}公共静态 IEnumerableGetAllInstances(){返回 ObjectFactory.GetAllInstances();}公共静态 IEnumerable GetAllInstances(类型类型){返回 ObjectFactory.GetAllInstances(type);}公共静态对象 GetInstance(类型类型){返回 ObjectFactory.GetInstance(type);}public static void Inject(T obj){ObjectFactory.Inject(obj);}}

我添加了包装器,假设我可能想在生产线的某个时候更改 IoC 容器.在这一点上,我认为这很糟糕.一个原因是:我不能在我的代码中使用 ObjectFactory 来做其他有趣的事情,我必须使用这个包装器.另一件事是:我们的代码不应该真正独立于 DependencyInjection 容器.

使用这种方法的利弊是什么?

解决方案

为此Common Service Locator 项目已经被开发出来.它是对 DI 框架的抽象,它定义了一个很像 IoC 类的接口.我什至开发了 Simple Service Locator 库;一个直接实现 Common Service Locator 接口的 DI 库.

所以从这个意义上说,对 DI 框架进行抽象并不奇怪.但是,当正确(并且完全)进行依赖注入时,其想法是相应地调整应用程序的设计,在应用程序根目录中配置容器,并且最好在应用程序中只有一个位置组装类型(阅读:GetInstance 被调用).对于 ASP.NET MVC 应用程序,这将是 ControllerFactory.对于 ASP.NET WebForms 应用程序,您通常需要覆盖 PageHandlerFactory.

当您遵守这些规则时,没有理由使用这样的抽象,因为无论如何您都只是在应用程序的一个地方调用容器.但是,如果这对您来说不可行,则使用 Common Service Locator 或您自己的抽象是一种替代方法.

但是在决定让代码依赖于对 IoC 库的抽象之前请退后一步,因为这会导致很多问题并且 通常被视为一种反模式.从代码中回调容器:

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

I have been using StructureMap for more than a year now. And all this time I used to have a wrapper class called IoC which looked like this

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

I added the wrapper assuming that I might want to change the IoC container at some point down the line. At this point I am thinking this is bad. One reason is: I cannot use ObjectFactory in my code to do other interesting things, I have to use this wrapper. The other thing is: Our code shouldn't really have to be independent of the DependencyInjection container.

What are the pros/cons of using this approach?

解决方案

For this reason the Common Service Locator project has been developed. It is an abstraction over DI frameworks and it defines an interface much like your IoC class. I even developed the Simple Service Locator library; an DI library that is a direct implementation of the Common Service Locator interface.

So in that sense, it's not weird to have an abstraction over DI frameworks. However, when doing Dependency Injection correctly (and completely), the idea is to adjust the design of your application accordingly, configure the container in the application root, and have preferably just a single place in the application were types are assembled (read: were GetInstance is called). For an ASP.NET MVC application, this would be the ControllerFactory. For ASP.NET WebForms application you would typically need to override a PageHandlerFactory.

When you play by these rules, there is no reason to use such an abstraction, because you just call the container at a single place in your application anyway. However, if that's not feasible for you, using either the Common Service Locator or your own abstraction is an alternative.

But please take a step back before you decide to let your code depend on an abstraction over your IoC library, because this causes a lot of problems and is seen as an anti-pattern in general. Calling back into the container from within your code:

  • Makes the code much harder to test.
  • Hides dependencies instead making the code harder to read and maintain.
  • Disables compile-time support.
  • Disallows your dependency graphs to be verified by a tool.

这篇关于为您的 IoC 包装一个好主意吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆