unitycontainer / microsoft-dependency-injection

Unity.Microsoft.DependencyInjection package
Apache License 2.0
63 stars 36 forks source link

Nested injections are not in the correct scope #89

Open Naun opened 3 years ago

Naun commented 3 years ago

Hi,

I need your help to understand if the following behavior is the expected one or if there is a trick to make it work. It seems that when there are nested dependency injections, the scope registrations are not taken into account. To make it clearer, I was expecting this test to pass, but it does not. It is failing to the last assertion:

[TestMethod]
public void NestedInjection_CreateChildContainer()
{
    IUnityContainer unityContainer = new UnityContainer();
    var serviceCollection = new ServiceCollection();
    serviceCollection.AddScoped<DbContext>(p => new DbContext());
    serviceCollection.AddScoped<Repository>(p => new Repository(p.GetService<DbContext>()));
    serviceCollection.BuildServiceProvider(unityContainer);

    // Creating a child container via unity
    var repositoryInstance1 = unityContainer.CreateChildContainer().Resolve<Repository>();
    var repositoryInstance2 = unityContainer.CreateChildContainer().Resolve<Repository>();

    // Instances of repository should be different
    Assert.AreNotEqual(repositoryInstance1.GetHashCode(), repositoryInstance2.GetHashCode());

    // Instances of dbcontext should be different
    Assert.AreNotEqual(repositoryInstance1.Context.GetHashCode(), repositoryInstance2.Context.GetHashCode());
}

My question is: does unity container creates a new scope when creating a child container?

Full test class: NestedInjectionTests.log

Amleto commented 3 years ago

@Naun AddScoped registers the service with container lifetime. If you want the child container to have its own instance, then register the service in the child container, not the root, or make sure the service is registered in unity container with hierarchical lifetime

Naun commented 3 years ago

Hi Amleto,

Thank you for your answer. But, that does not explain:

  1. Why Repositories instances are differents whereas they are also registered as Scoped?
  2. And additionally, if I write serviceCollection.AddScoped<DbContext>(); instead of using the lambda expression, the unit test passes: it provides two different instances of DbContext... Why?