为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

C#
绝地无双 2019-08-27 13:40:54
创建单例来访问统一容器或通过应用程序传递它是否更好?我正在使用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);     } }我可以看到三个选项:创建一个Singleton来存储我可以在任何地方访问的Unity容器。我真的不喜欢这种方法。添加这样的依赖项来使用依赖注入框架似乎有点奇怪。将IUnityContainer传递给我的TestSuiteParser类及其中的每个子类(假设它是n级深度或实际上大约3级深度)。在任何地方传递IUnityContainer只是看起来很奇怪。我可能只需要克服这一点。在正确的方式上使用Unity的灯泡时刻。希望有人可以帮助轻弹开关。[编辑]我不清楚的一件事是我想为foreach语句的每次迭代创建一个新的测试用例实例。上面的示例需要解析测试套件配置并填充测试用例对象的集合
查看完整描述

3 回答

?
蝴蝶不菲

TA贡献1810条经验 获得超4个赞

DI的正确方法是使用构造函数注入或其他DI模式(但最常见的是构造函数注入)将依赖项注入到使用者中,而不管DI Container如何

在你的榜样,它看起来像你需要的依赖TestSuiteTestCase,所以你TestSuiteParser类应该静态地宣布,它通过其(只)构造要求他们需要这些依赖关系:

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

    // ...}

注意如何组合readonly关键字和保护条款保护类的不变量,确保依赖提供给TestSuiteParser的任何成功创建实例。

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

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

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

(但是,我怀疑可能涉及多个TestCase,在这种情况下,您可能需要注入抽象工厂而不是单个TestCase。)

从您的Composition Root,您可以配置Unity(或任何其他容器):

container.RegisterType<TestSuite, ConcreteTestSuite>();container.RegisterType<TestCase, ConcreteTestCase>();container.RegisterType<TestSuiteParser>();var parser = container.Resolve<TestSuiteParser>();

当容器解析TestSuiteParser时,它理解构造函数注入模式,因此它使用所有必需的依赖项自动连接实例。

创建一个Singleton容器或传递容器只是Service Locator反模式的两种变体,所以我不建议这样做。


查看完整回答
反对 回复 2019-08-27
  • 3 回答
  • 0 关注
  • 355 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信