Как запретить DryIoc утилизировать синглтоны в дочернем контейнере dispose

#c# #dryioc

#c# #dryioc

Вопрос:

Я хочу использовать дочерний контейнер из DryIoc, но каким-то образом он удаляет синглтоны из родительского контейнера. Как я могу создать дочерний контейнер, который разрешает экземпляры singleton, но не удаляет их?

     [Test]
    public void Test1()
    {
        IService service;
        using (var parent = new Container())
        {
            parent.Register<IService, Service>(Reuse.Singleton);
            service = parent.Resolve<IService>();
            using (var child = parent.With(parent.Rules, parent.ScopeContext, RegistrySharing.CloneAndDropCache, parent.SingletonScope.Clone()))
            {
                var service2 = child.Resolve<IService>();
                Assert.AreEqual(service, service2);
            }
            Assert.IsFalse(service.IsDisposed); //child container disposed parent singleton!!!
        }
        Assert.IsTrue(service.IsDisposed);
    }

    public interface IService
    {
        bool IsDisposed { get; }
    }

    public class Service : IService, IDisposable
    {
        public void Dispose() => IsDisposed = true;
        public bool IsDisposed { get; private set; }
    }
  

Ответ №1:

Если утилизация дочернего контейнера вызывает проблемы, просто не утилизируйте его 🙂 Спасибо Дадхи.

 using (var child = parent.With(parent.Rules, parent.ScopeContext, RegistrySharing.CloneAndDropCache, parent.SingletonScope.Clone())
.OpenScope()) // Here!
  

Нет необходимости утилизировать дочерний контейнер, потому что при открытии новой области все одноразовые объекты будут отслеживаться внутри явной области.

Ответ №2:

Вместо этого вы можете открыть контекст с ограниченной областью, и он будет работать, как ожидалось. Существует не так много причин, по которым вам нужен дочерний контейнер, который не может решить контекст с ограниченной областью действия.

 using (var child = parent.OpenScope())
{
    var service2 = child.Resolve<IService>();
    Assert.AreEqual(service, service2);
}