Skip to content

Dispose child container without disposing parent #269

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
mwhelan opened this issue May 2, 2020 · 7 comments
Closed

Dispose child container without disposing parent #269

mwhelan opened this issue May 2, 2020 · 7 comments

Comments

@mwhelan
Copy link

mwhelan commented May 2, 2020

Hi

I am wanting to create the main container when my tests start, then create a child container for each test that is disposed at the end of the test. However, I was surprised to find that when I dispose the child container the parent is also disposed. Is there a way to change this behaviour?

[Test]
public void should_dispose_child_without_disposing_parent()
{
    var parent = new Container();
    var child = parent.CreateFacade();  // same with WithRegistrationsCopy()
    child.Register<IService, Service>();

    child.Dispose();

    Assert.IsFalse(parent.IsDisposed);   // this line fails
}

Creating a child container with parent.OpenScope() works for disposing it without disposing the parent, but I don't think it lets me register items, which I would like to do.

Any advice much appreciated! Thanks.

@dadhi
Copy link
Owner

dadhi commented May 2, 2020

Related #259.

@mwhelan
Copy link
Author

mwhelan commented May 2, 2020

Thanks. So, it doesn't seem that it is possible at the moment. I look forward to hearing if this is the intended design or whether you might change it in the future.

@dadhi
Copy link
Owner

dadhi commented May 2, 2020

Check a more generic .With(...) method for the possible options, e.g. #259 has an example. Meanwhile I will check what's hapenning here.

Creating a child container with parent.OpenScope() works for disposing it without disposing the parent, but I don't think it lets me register items

There is a way to add lightweight "registration" directly to scope via Use method:

var parent = new Container();
using (var test = parent.OpenScope())
{
    test.Use<IService>(new MockService());
}

@mwhelan
Copy link
Author

mwhelan commented May 2, 2020

OK, that's worth giving a go. Thanks again for the fast responses. Always appreciated.

@mwhelan
Copy link
Author

mwhelan commented May 9, 2020

Just to update, your suggestions of using the more generic .With(...) method from 259 worked thanks. I can create a child container, override any registrations I want, and then when I dispose the child the parent is no longer disposed as well.

[Test]
public void child_lifecycle_should_be_independent_of_parent_lifecycle()
{
    var parent = new Container(rules => rules
        .WithConcreteTypeDynamicRegistrations());
    parent.Register<IService, Service>(Reuse.Singleton);

    // child can override parent registrations and parent is unchanged
    var child = CreateChildContainer(parent);
    child.UseInstance<IService>(new TestService(), IfAlreadyRegistered.Replace);
    child.Resolve<Concrete>().Service.ShouldBeOfType<TestService>();
    parent.Resolve<Concrete>().Service.ShouldBeOfType<Service>();
    
    // when child is disposed parent is unaffected
    child.Dispose();
    child.IsDisposed.ShouldBeTrue();
    parent.IsDisposed.ShouldBeFalse();
}

private IContainer CreateChildContainer(Container parent)
{
    var child = parent.With(
        parent.Rules,
        parent.ScopeContext,
        RegistrySharing.CloneAndDropCache,
        parent.SingletonScope.Clone());
    return child;
}

public interface IService { }
public class Service : IService { }
public class TestService : IService { }
public class Concrete
{
    public IService Service { get; }
    public Concrete(IService service)
    {
        Service = service;
    }
}

Thanks again for your help and for the excellent framework.

@dadhi
Copy link
Owner

dadhi commented May 9, 2020

@mwhelan Thanks for update, If you Ok I want to add this example to the docs.

@mwhelan
Copy link
Author

mwhelan commented May 9, 2020

Yes, that’s fine with me.

@mwhelan mwhelan closed this as completed May 9, 2020
dadhi pushed a commit that referenced this issue Sep 1, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants