The right approach to DI is to use Constructor Injection or another DI template (but the most typical is constructor introduction) to embed dependencies to the consumer, regardless of the DI container .
In your example, it looks like you need TestSuite and TestCase dependencies, so your TestSuiteParser class should statically declare that it requires these dependencies, asking them through the (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; }
Notice how the combination of the readonly keyword and the Guard block protects class invariants, ensuring that dependencies are available to any successfully created TestSuiteParser instance.
Now you can implement the Parse method as follows:
public TestSuite Parse(XPathNavigator someXml) { List<XPathNavigator> aListOfNodes = DoSomeThingToGetNodes(someXml) foreach (XPathNavigator blah in aListOfNodes) { this.testSuite.TestCase.Add(this.testCase); } }
(however, I suspect that more than one TestCase may be involved, in which case you can add an abstract Factory instead of a single TestCase.)
From 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>();
When the container allows TestSuiteParser, it understands the constructor installation pattern, so it is an Auto-Wires instance with all the necessary dependencies.
Creating a Singleton container or transferring a container are just two variations of the Locator antivirus program , so I would not recommend that.
Mark Seemann Mar 05 '10 at 12:27 2010-03-05 12:27
source share