【问题标题】:IoC Container. Inject container国际奥委会容器。注射容器
【发布时间】:2016-11-11 12:55:23
【问题描述】:

我想要什么:解析对象 A,在对象 A 内部,我想使用同一个容器来解析对象 C:

public static void Work()
{
    IUnityContainer con = new UnityContainer();
    con.RegisterType<IA, A>();
    con.RegisterType<IB, B>();
    con.RegisterType<IC, C>();

    var a = con.Resolve<IA>();
}


interface IA { }
interface IB { }
interface IC { }

class A : IA
{
    public A(IB b, IUnityContainer con)
    {
        for (int i = 0; i < 10; i++)
        {
            var c = con.Resolve<IC>();
        }
    }
}

class B : IB { };
class C : IC { };

问题:在很多网站上,我看到注入容器是个坏主意,但在这种情况下怎么办?

编辑 1

服务定位器是一种反模式。那么如果可以将 Service Locator 与 IoC Container 一起使用,为什么可以呢?

【问题讨论】:

  • 我从你的问题中遗漏的是 what question 你想在这里解决。为什么需要多次解析IC 以及为什么需要在A 的构造函数中执行此操作。您能否通过使用真实姓名使您的用例更加具体,并描述您在做什么以及为什么?
  • @Steven 我想在我的应用程序的许多地方使用容器。我的解决方案是到处注入那个容器。我知道到处注入它是个坏主意,但服务定位器被称为反模式和静态类更糟糕。
  • 这是我很清楚的部分。我不清楚的是您的具体用例。请用一个真实的例子详细说明,而不是像AIC这样的类。

标签: c# inversion-of-control unity-container ioc-container


【解决方案1】:

您不应该传递对您的类的直接引用,因为这会使您的代码依赖于所使用的 IOC 容器(此处为 UnityContainer),并使单元测试更加困难。

如果您的 A 类需要多个 C 实例,您应该为这种情况定义一个工厂,并将该工厂的一个实例传递给您的 A 类。您的真实工厂可以引用 UnityContainer。对于单元测试,您可以模拟接口并将模拟实例传递给您的 A 类。

这个代码看起来像这样。

public interface IClassICFactory
{
    IC CreateInstance();
}

public class ClassICUnityContainerFactory : IClassCFactory
{
    private IUnityContainer _container;

    public ClassICUnityContainerFactory(IUnityContainer container)
    {
        _container = container;
    }

    public IC CreateInstance()
    {
        return _container.Resolve<C>();
    }
}

class A : IA
{
    public A(IB b, IClassICFactory factory)
    {
        for (int i = 0; i < 10; i++)
        {
            var c = factory.CreateInstance();
        }
    }
}

【讨论】:

    【解决方案2】:

    虽然从技术上讲它有效,但它有点“容器化”,会导致大量混乱。我为处理这类事情的容器创建静态工厂类。由容器解析的类实例应该只关心它们的用途,而不是进一步解析其他实例。

    【讨论】:

    • 但是它不允许你注入模拟对象,如果你引用静态工厂,它就不再可测试了。
    • 那是因为静态类是它们自己的实现。您无需提供实例。只需访问测试中的静态类
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-06
    相关资源
    最近更新 更多