tags:

views:

746

answers:

3

Greetings

Is there a way for a unity container to pass itself to an object?

i.e.:

public class Something {

     public Something(IUnityContainer container) {
           ...
     }
}

Thank you for the help.

+5  A: 

The short answer is yes.

This should be passed automatically when you use the Resolve methods.

For example:

IUnityContainer container = new UnityContainer();
var something = container.Resolve<Something>();

Additionally, this is the same technique that Prism (on CodePlex) uses if you want to look into that.

Update Added Test:

[TestClass]
public class Spike
{
    [TestMethod]
    public void unityTest()
    {
        var container = new UnityContainer();
        var something= container.Resolve<Something>();
        Assert.AreSame(container, something.Container);
        // This passes. Success.
    }
}

public class Something
{
    public Something(IUnityContainer container)
    {
        Container = container;
    }

    public IUnityContainer Container { get; set; }
}
bendewey
There's no need to register the container with itself. It will resolve the IUnityContainer dependency to itself by default.
Kiff
I didn't have the time to run the spike last night thanks for pointing that out. I added the test I used.
bendewey
A: 

As bendewey mentioned you can pass it, as it is an object, like any other object, but, why pass it?

You have only one, why not have it be a static property that any class can access?

James Black
The concern I have with this approach is that it can cause unnecessary dependencies on the project that contains static class. In my experience, injecting the container also helps testing.
bendewey
For the same reason that static accessors aren't used for other dependencies: it complicates testability.
Kiff
Rather than having logic in the unit test framework for getting the container it would be better, IMO, to have a separate class for dealing with the container, so that you can test that class. You now know that it works properly, so your unit test isn't using something untested. I try to have very few utility functions in a unit test, as those should also be tested.
James Black
+1  A: 

The first answer is sort of what I was thinking. Thank you.

Prior to Unity, we built our own IOC container, and we have a syntax something like...

<constructor>
    <param name="factory" value="[{factory}]"/>
</constructor>

The [{factory}] causes it to pass itself as the parameter.

As for setting it as a static: I don't like using that approach because the every object becomes dependent on the single property (obviously). Its less reusable and less testable, especially if the static is readonly (which it should be). Once the static is set, you can't (or shouldn't be able to) mess with it, which limits the test scenarios you can create.

If nothing else, then the objects should at least be able to accept a container as a parameter. If its not there, then it could fall back to a static.

We've gone down the road of using the single instance, and ended up changing it all. In my opinion, the objects should be more flexible than that. If the consumer of the objects wants to have a single instance that it passes to its objects, that's up to the consumer. But, the object themselves shouldn't require it. With the syntax shown above, its really easy to pass the container through the graph.

Thanks for the info.

Jay

Sorry... new guy. I see now this should've been a comment, not an answer.

Jay Allard
This could also have been phrased as an update to your original question. Also keep in mind, voting can take the "first answer" comment out of context.
bendewey