Утилизировать или не утилизировать инъецируемый экземпляр с помощью Ninject

У меня есть следующий блок кода для настройки Ninject в моем решении:

public class NinjectDependencyScope : IDependencyScope
    {
        private IResolutionRoot resolver;

        internal NinjectDependencyScope(IResolutionRoot resolver)
        {
            Contract.Assert(resolver != null);

            this.resolver = resolver;
        }

        public object GetService(Type serviceType)
        {
            if (resolver == null)
            {
                throw new ObjectDisposedException("this", "This scope has already been disposed");
            }

            return resolver.TryGet(serviceType);
        }

        public IEnumerable<object> GetServices(Type serviceType)
        {
            if (resolver == null)
            {
                throw new ObjectDisposedException("this", "This scope has already been disposed");
            }

            return resolver.GetAll(serviceType);
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        protected virtual void Dispose(bool disposing)
        {
            if (disposing)
            {
                IDisposable disposable = resolver as IDisposable;
                if (disposable != null)
                {
                    disposable.Dispose();
                }

                resolver = null;
            }
        }

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

IDependencyScope является IDisposable, но я должен очищать только IDisposable члены, если я их конструирую, но внедренный преобразователь в конструкторе не принадлежит (не создан) моим классом, а IResolutionRoot не наследуется от / внедряет IDisposable...

Я прямо здесь?

(проверьте эту статью о IDisposable шаблон для справки)

(правка): На самом деле это базовый класс, используемый следующим классом, поэтому удалить реализацию IDisposable здесь нельзя...

public class NinjectDependencyResolver : NinjectDependencyScope, IDependencyResolver
    {
        private IKernel kernel;

        public NinjectDependencyResolver(IKernel kernel)
            : base(kernel)
        {
            this.kernel = kernel;
        }

        public IDependencyScope BeginScope()
        {
            return new NinjectDependencyScope(kernel.BeginBlock());
        }
    }

3 ответа

Мой опыт работы с Ninject заключается в том, что когда речь идет об управляемых объектах, реализующих IDisposable, вам не нужно беспокоиться так сильно, как они в конечном итоге будут удалены.

Однако, если у вас есть одноразовые объекты, которые являются обертками вокруг неуправляемых объектов (например, класс C#, обертывающий объект Office Interop Application), вам нужно быть более внимательным, так как в конечном итоге они будут удалены Ninject, но вы можете: Т достоверно сказать, когда.

Иногда вам нужно быстро очистить эти ресурсы, так как другие части вашего кода могут полагаться на то, что эти ресурсы уже очищаются (например, вы можете "использовать" один из этих объектов для создания рабочей книги, а затем нужно переименовать рабочую книгу вскоре после этого вам нужно освободить объект Application).

В подобном сценарии я могу нарушить принцип DI, и просто обновлять объект, когда использую его, и распоряжаться им самостоятельно.

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

Следующая миминальная имплементация верна (при условии, что ни этот класс, ни производный от него класс не используют неуправляемые ресурсы - что редко бывает):

public void Dispose() {
    IDisposable disposable = resolver as IDisposable;
    if (disposable != null) {
        disposable.Dispose();
    }
    resolver = null;
}

Смотрите Minimal IDispose для подробностей.

Это необязательно, так как распознаватель будет корректно удален без него, т.е. необходим только в том случае, когда вам особенно необходимо контролировать высвобождение ресурсов, управляемых ресовлером (что?).

Я знаю, что это имеет место с Autofac. Вам не нужно беспокоиться об удалении классов, которые вы разрешили из Autofac, потому что он вызовет dispose для вас. Я уверен, что Ninject будет похожим.

Другие вопросы по тегам