猿问

创建单例来访问统一容器或通过应用程序传递它是否更好?

创建单例来访问统一容器或通过应用程序传递它是否更好?

我正在使用IoC框架,我选择使用Unity。我还没有完全理解的一件事是如何更深入地解析应用程序中的对象。我怀疑我当时还没有灯泡可以说清楚。

因此,我尝试在psuedo'ish代码中执行以下操作

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

所以testSuiteParser.Parse执行以下操作

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

我可以看到三个选项:

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

  2. 将IUnityContainer传递给我的TestSuiteParser类及其中的每个子类(假设它是n级深度或实际上大约3级深度)。在任何地方传递IUnityContainer只是看起来很奇怪。我可能只需要克服这一点。

  3. 在正确的方式上使用Unity的灯泡时刻。希望有人可以帮助轻弹开关。

[编辑]我不清楚的一件事是我想为foreach语句的每次迭代创建一个新的测试用例实例。上面的示例需要解析测试套件配置并填充测试用例对象的集合


绝地无双
浏览 356回答 3
3回答

蝴蝶不菲

DI的正确方法是使用构造函数注入或其他DI模式(但最常见的是构造函数注入)将依赖项注入到使用者中,而不管DI Container如何。在你的榜样,它看起来像你需要的依赖TestSuite和TestCase,所以你TestSuiteParser类应该静态地宣布,它通过其(只)构造要求他们需要这些依赖关系:public&nbsp;class&nbsp;TestSuiteParser{ &nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;readonly&nbsp;TestSuite&nbsp;testSuite; &nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;readonly&nbsp;TestCase&nbsp;testCase; &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;TestSuiteParser(TestSuite&nbsp;testSuite,&nbsp;TestCase&nbsp;testCase) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(testSuite&nbsp;==&nbsp;null) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw&nbsp;new&nbsp;ArgumentNullException(testSuite); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(testCase&nbsp;==&nbsp;null) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw&nbsp;new&nbsp;ArgumentNullException(testCase); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.testSuite&nbsp;=&nbsp;testSuite; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.testCase&nbsp;=&nbsp;testCase; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;...}注意如何组合readonly关键字和保护条款保护类的不变量,确保依赖将提供给TestSuiteParser的任何成功创建实例。您现在可以像这样实现Parse方法:public&nbsp;TestSuite&nbsp;Parse(XPathNavigator&nbsp;someXml)&nbsp;{&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;List<XPathNavigator>&nbsp;aListOfNodes&nbsp;=&nbsp;DoSomeThingToGetNodes(someXml)&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;foreach&nbsp;(XPathNavigator&nbsp;blah&nbsp;in&nbsp;aListOfNodes)&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;{&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.testSuite.TestCase.Add(this.testCase);&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;}(但是,我怀疑可能涉及多个TestCase,在这种情况下,您可能需要注入抽象工厂而不是单个TestCase。)从您的Composition Root,您可以配置Unity(或任何其他容器):container.RegisterType<TestSuite,&nbsp;ConcreteTestSuite>();container.RegisterType<TestCase,&nbsp;ConcreteTestCase>();container.RegisterType<TestSuiteParser>();var&nbsp;parser&nbsp;=&nbsp;container.Resolve<TestSuiteParser>();当容器解析TestSuiteParser时,它理解构造函数注入模式,因此它使用所有必需的依赖项自动连接实例。创建一个Singleton容器或传递容器只是Service Locator反模式的两种变体,所以我不建议这样做。
随时随地看视频慕课网APP
我要回答