2016-11-11 99 views
2

我想要什么:解决对象A和对象A的内部,我想用同一个容器来解决对象C:IoC容器。注入容器

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

问题:在许多网站我看到注入容器是坏主意,但如何处于这种情况?

EDIT 1

服务定位器是一个反模式。因此,如果可以使用Service Locator和IoC Container,为什么它可以?

+1

我从你的问题缺少的是*你在这里试图解决什么问题。为什么你需要多次解析'IC',为什么你需要在'A'的构造函数中做这个。你能否通过使用真实姓名来更具体地描述你的用例,并描述你在做什么,为什么? – Steven

+0

@Steven我想在我的应用程序的许多地方使用容器。我的解决方案是到处注入该容器。我知道注入到处都是坏主意,但服务定位器被称为反模式和静态类更糟糕。 –

+1

这是我清楚的部分。我不清楚的是你的具体用例。请详细说明一个真实的例子,而不是像'A'和'IC'这样的类。 – Steven

回答

3

你不应该传递给你的类的直接引用,因为这将使你的代码依赖于使用的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(); 
     } 
    } 
} 
0

虽然技术上有效,但它有点'容器',会导致大量的混淆。我为处理这种事情的容器创建静态工厂类。您通过容器解决的类实例应该只关心他们打算做什么,而不是进一步解决其他实例。

+0

但是,如果您引用静态工厂,它不会让您注入模拟对象并且不再可测试。 –

+0

那是因为静态类是他们自己的实现。你不需要提供一个实例。只需在您的测试中访问静态类 –