【问题标题】:Dispose or not dispose injectable instance using Ninject使用 Ninject 处理或不处理可注入实例
【发布时间】:2013-10-21 09:15:59
【问题描述】:

我的解决方案中有以下用于配置 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...

我在这里吗?

(查看this关于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());
        }
    }

【问题讨论】:

    标签: c# dispose idisposable disposable


    【解决方案1】:

    我对 Ninject 的体验是,当涉及到实现 IDisposable 的托管对象时,您不必太担心,因为它们最终会被丢弃。

    但是,如果您有一次性对象是非托管对象的包装器(例如,包装了 Office 互操作应用程序对象的 C# 类),那么您需要更加小心,因为这些最终会被 Ninject 处理掉,但是你不能确切地说什么时候。

    有时您需要快速清理这些资源,因为您的代码的其他部分可能依赖于已清理的这些资源(例如,您可能正在“使用”其中一个对象来创建工作簿,然后需要不久之后重命名工作簿,此时您需要释放 Application 对象)。

    在这种情况下,我可能会违反 DI 原则,在使用的时候新建一个对象,然后自己处理掉。

    我想你自己测试一下,这样你就知道哪些对象适合与 Ninject 一起使用,哪些不适合并相应地这样做。

    【讨论】:

      【解决方案2】:

      我知道 Autofac 就是这种情况。你不应该担心释放你从 Autofac 解析的类,因为它会为你调用 dispose。我很确定 Ninject 会很相似。

      【讨论】:

        【解决方案3】:

        以下最小实现是正确的(前提是此类或从它派生的类都不使用非托管资源 - 这种情况很少发生):

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

        详情请参阅Minimal IDispose implementation

        它是可选的,因为解析器将在没有它的情况下正确处理 - 即仅在您特别需要控制自己释放解析器管理的资源时才需要(什么?) .

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2017-10-09
          • 1970-01-01
          • 1970-01-01
          • 2012-05-13
          • 1970-01-01
          • 2011-02-02
          • 1970-01-01
          相关资源
          最近更新 更多