Matt Knowles
Matt Knowles

Reputation: 397

Why is Structuremap's Transient lifecycle treated like ContainerScoped on nested containers?

I have the following class declaration and unit test:

    public class Blah { }

    [TestMethod]
    public void TestMethod1()
    {
        var container = new Container();

        var instance1 = container.GetInstance<Blah>();
        var instance2 = container.GetInstance<Blah>();

        var areBothInstancesSame = instance1 == instance2;

        var nested = container.GetNestedContainer();

        var nestedInstance1 = nested.GetInstance<Blah>();
        var nestedInstance2 = nested.GetInstance<Blah>();

        var areBothNestedInstancesSame = nestedInstance1 == nestedInstance2;
    }

When I run this test, areBothInstancesSame is false but areBothNestedInstancesSame is true.

I also tested this inside a Web Api controller action:

    public class Blah { }

    public IHttpActionResult GetBlah()
    {
        var scope = this.Request.GetDependencyScope();

        var instance1 = (Blah)scope.GetService(typeof(Blah));
        var instance2 = (Blah)scope.GetService(typeof(Blah));

        var areBothInstancesSame = instance1 == instance2;

        return this.Ok();
    }

And again, areBothInstancesSame is true.

I see this described in Structuremap's documentation, so I believe it's working as intended, but I don't understand why this is intended or how to get the nested container that Web Api automatically creates to return a new instance for each service with a Transient lifecycle.

Can anyone help me understand: 1) why this is the intended default behavior and how to make the nested container return a new instance every time; or 2) why it's obvious that I should never want the nested container to return a new instance every time?

Thanks

Upvotes: 2

Views: 760

Answers (1)

Alex D.
Alex D.

Reputation: 121

The best answer I can give is that the word nested refers rather to container's services and not necessarily to container hierarchy as it may seem (that is why child containers exist also) Getting a service instance from a normal container will create a new instance along with the full object graph, with all required nested services inside. No mater how may times some transient service is nested inside the object graph, only one instance is created for that service type and reused within the entire graph.

For a nested container the transient instances behave as they belong to(are nested inside) the same object graph because it's purpose is to be used within one logical request.

maybe this example will help with the usage of nested containers http://structuremap.github.io/the-container/nested-containers/#sec5

basically nested containers exist to ensure transient services will not get a new instance with each GetService call.

To make a nested container return a new instance every time you should register the service as AlwaysUnique

Upvotes: 1

Related Questions