我专心使用IoC框架,并且选择使用Unity。我仍然不完全了解的一件事是如何在应用程序的更深处解析对象。我怀疑我只是没有把灯泡弄清楚。
所以我正在尝试在伪代码中执行以下操作
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); } }
我可以看到三个选项:
[编辑]我不清楚的一件事是,我想为foreach语句的每次迭代创建一个新的测试用例实例。上面的示例需要解析测试套件配置并填充测试用例对象的集合
DI的正确方法是使用 构造函数注入 或其他DI模式(但最常见的是Constructor Injection)将依赖项注入到使用者中, 而与DI Container无关 。
在您的示例中,看起来您需要依赖项TestSuite和TestCase,因此您的TestSuiteParser类应通过(仅)构造函数要求它们来 静态声明 它需要这些依赖项:
TestSuite
TestCase
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的任何成功创建实例。
readonly
您现在可以像这样实现Parse方法:
public TestSuite Parse(XPathNavigator someXml) { List<XPathNavigator> aListOfNodes = DoSomeThingToGetNodes(someXml) foreach (XPathNavigator blah in aListOfNodes) { this.testSuite.TestCase.Add(this.testCase); } }
(但是,我怀疑可能涉及多个TestCase,在这种情况下,您可能想注入一个Abstract Factory而不是一个TestCase。)
在您的Composition Root中,您可以配置Unity(或任何其他容器):
container.RegisterType<TestSuite, ConcreteTestSuite>(); container.RegisterType<TestCase, ConcreteTestCase>(); container.RegisterType<TestSuiteParser>(); var parser = container.Resolve<TestSuiteParser>();
当容器解析TestSuiteParser时,它将理解构造函数注入模式,因此它将 自动 连接实例及其所有必需的依赖项。
创建Singleton容器或将容器四处传递只是Service Locator反模式的两个变体,所以我不建议这样做。