1

我有以下代码块用于在我的解决方案中配置 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());
        }
    }
4

3 回答 3

1

我对 Ninject 的经验是,当涉及到实现 IDisposable 的托管对象时,您不必担心它们最终会被处理掉。

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

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

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

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

于 2013-10-21T09:58:37.367 回答
0

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

于 2013-10-21T09:18:43.220 回答
0

The following miminal implimentation is correct (provided that neither this class or a class that derives from it uses UNmanaged resources - which is rarely the case):

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

See Minimal IDispose implementation for details.

It is optional as the resolver will be correctly disposed with out it - i.e only necessary in the case when you particularly need to control yourself the release of the resources managed by the resovler (what?).

于 2013-10-21T13:31:44.967 回答