使用Ninject配置或不配置可注射实例

时间:2013-10-21 09:15:59

标签: c# dispose idisposable disposable

我有以下代码块用于在我的解决方案中配置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模式的this文章以供参考)

(适用编辑): 这实际上是一个基类,由以下类使用,因此无法在此处删除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 个答案:

答案 0 :(得分:0)

我知道Autofac就属于这种情况。你不应该担心处理你从Autofac解决的类,因为它会为你调用dispose。我很确定Ninject会很相似。

答案 1 :(得分:0)

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

但是,如果你有一些一次性对象是非托管对象周围的包装器(例如一个围绕Office Interop Application对象的C#类),那么你需要更加小心,因为它们最终会被Ninject处理掉,但是你不能可靠地说什么时候。

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

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

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

答案 2 :(得分:0)

以下的miminal implimentation是正确的(前提是这个类或派生自它的类都不使用非托管资源 - 这种情况很少发生):

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

有关详细信息,请参阅Minimal IDispose implementation

这是可选的,因为解析器将被正确处理掉 - 即只有当您特别需要控制自己释放resovler管理的资源时才需要(什么?)