它是最好创建一个单独访问统一的容器或通过它通过应用程序? [英] Is it better to create a singleton to access unity container or pass it through the application?

查看:86
本文介绍了它是最好创建一个单独访问统一的容器或通过它通过应用程序?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我蘸我的脚趾到使用IoC框架,我已经选择使用统一。其中的事情,我还是不完全了解是如何解决更深的应用对象。我怀疑我只是还没有对那一刻的灯泡,这将使它明确。

I am dipping my toe into using a IoC framework and I have choosen to use Unity. One of the things that I still don't fully understand is how to resolve objects deeper into the application. I suspect I just haven't had the light bulb on moment that will make it clear.

所以我试图做这样的事情在psuedo'ish code以下

So I am trying do something like the following in psuedo'ish code

void Workflow(IUnityContatiner contatiner, XPathNavigator someXml)
{
   testSuiteParser = container.Resolve<ITestSuiteParser>
   TestSuite testSuite = testSuiteParser.Parse(SomeXml) 
   // Do some mind blowing stuff here
}

所以testSuiteParser.Parse执行以下操作

So the testSuiteParser.Parse does the following

TestSuite Parse(XPathNavigator someXml)
{
    TestStuite testSuite = ??? // I want to get this from my Unity Container
    List<XPathNavigator> aListOfNodes = DoSomeThingToGetNodes(someXml)

    foreach (XPathNavigator blah in aListOfNodes)
    {
        //EDIT I want to get this from my Unity Container
        TestCase testCase = new TestCase() 
        testSuite.TestCase.Add(testCase);
    } 
}

我可以看到三个选项:

I can see three options:


  1. 创建一个Singleton来存储我的,我可以在任何地方访问统一的容器。我真的不是这种方法的粉丝。添加这样的依赖使用依赖注入框架似乎有点对奇方。

  2. 传递IUnityContainer我TestSuiteParser类和它的每一个孩子(假设它是N级深或在现实中约3级深)。传递IUnityContainer到处只是看起来很奇怪。我可能只需要得到这个了。

  3. 对使用统一的正确途径灯泡的时刻。希望有人能帮助轻弹开关。


其中的事情,我不是明确的是,我想创建测试用例的一个新实例为foreach语句的每个迭代。上面的例子需要解析的测试套件配置和填充测试用例对象的集合

One of things that I wasn't clear on is that I want to create a new instance of test case for each iteration of the foreach statement. The example above needs to parse a test suite configuration and populate a collection of test case objects

推荐答案

的正确途径DI是使用构造器注入或其他DI图案(但构造器注入是最常见的)注入依赖关系到消费者,不论DI容器

The correct approach to DI is to use Constructor Injection or another DI pattern (but Constructor Injection is the most common) to inject the dependencies into the consumer, irrespective of DI Container.

在你的榜样,它看起来像你需要依赖的TestSuite 测试用例,让您的TestSuiteParser类应当< STRONG>静态宣布,它需要这些依赖通过其头(只)构造要求他们:

In your example, it looks like you require the dependencies TestSuite and TestCase, so your TestSuiteParser class should statically announce that it requires these dependencies by asking for them through its (only) constructor:

public class TestSuiteParser
{
    private readonly TestSuite testSuite;
    private readonly TestCase testCase;

    public TestSuiteParser(TestSuite testSuite, TestCase testCase)
    {
        if(testSuite == null)
        {
            throw new ArgumentNullException(testSuite);
        }
        if(testCase == null)
        {
            throw new ArgumentNullException(testCase);
        }

        this.testSuite = testSuite;
        this.testCase = testCase;
    }

    // ...
}

注意只读关键字和保护条款的组合如何保护类的不变量,确保相关性的将会的是提供给任何成功创建TestSuiteParser的实例。

Notice how the combination of the readonly keyword and the Guard Clause protects the class' invariants, ensuring that the dependencies will be available to any successfully created instance of TestSuiteParser.

您现在可以实现Parse方法是这样的:

You can now implement the Parse method like this:

public TestSuite Parse(XPathNavigator someXml) 
{ 
    List<XPathNavigator> aListOfNodes = DoSomeThingToGetNodes(someXml) 

    foreach (XPathNavigator blah in aListOfNodes) 
    { 
        this.testSuite.TestCase.Add(this.testCase); 
    }  
} 

(不过,我怀疑有可能是涉及到多个测试用例,在这种情况下,你可能想要<一个href=\"http://stackoverflow.com/questions/1943576/is-there-a-pattern-for-initializing-objects-created-wth-a-di-container/1945023#1945023\">inject一个抽象工厂,而不是的单一的TestCase的。)

(however, I suspect that there may be more than one TestCase involved, in which case you may want to inject an Abstract Factory instead of a single TestCase.)

从您的<一个href=\"http://stackoverflow.com/questions/1475575/where-should-i-do-dependency-injection-with-ninject-2/1475861#1475861\">Composition根,您可以配置统一(或任何其他容器):

From your Composition Root, you can configure Unity (or any other container):

container.RegisterType<TestSuite, ConcreteTestSuite>();
container.RegisterType<TestCase, ConcreteTestCase>();
container.RegisterType<TestSuiteParser>();

var parser = container.Resolve<TestSuiteParser>();

当容器解析TestSuiteParser,它理解构造器注入模式,所以它自动线及其所有必需的依赖实例。

When the container resolves TestSuiteParser, it understands the Constructor Injection pattern, so it Auto-Wires the instance with all its required dependencies.

创建一个Singleton容器或传递容器周围都是服务定位器反模式的只有两个变化,所以我不会建议。

Creating a Singleton container or passing the container around are just two variations of the Service Locator anti-pattern, so I wouldn't recommend that.

这篇关于它是最好创建一个单独访问统一的容器或通过它通过应用程序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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