Is it better to create a singleton to access unity container or pass it through the application? [closed]

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.

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

    // ...
}

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.

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

(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.)

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

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

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.

Leave a Comment