在中介模式实现中将Ninject注入处理器以进行对象解析

时间:2015-09-18 11:20:25

标签: c# ninject heap-memory

我遇到了内存泄漏问题,我无法找到插件。它适用于桌面应用程序,而不是Web,因此对象的生命周期比单个请求更长。

我正在尝试实施这篇优秀博文中描述的架构 - https://www.cuttingedge.it/blogs/steven/pivot/entry.php?id=92

QueryProcessor 类需要一个IOC容器,因为它在调用 Process 方法时解析了具体类型。我的实现如下:

public sealed class QueryProcessor : IQueryProcessor, IDisposable
{
    private readonly IKernel _container;
    private bool _disposed;

    public QueryProcessor(IKernel container)
    {
        _container = container;
    }

    //[DebuggerStepThrough]
    public TResult Process<TResult>(IQuery<TResult> query)
    {
        var handlerType = typeof(IQueryHandler<,>).MakeGenericType(query.GetType(), typeof(TResult));

        dynamic handler = (_container.Target as IKernel).Get(handlerType);

        return handler.Handle((dynamic)query);
    }

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

    private void Dispose(bool disposing)
    {
        if (disposing && !_disposed)
        {
            // dispose container ???
            _disposed = true;
        }            
    }
}

我遇到的问题是,如果我注入Ninject内核,则意味着 QueryProcessor 类在超出范围时不会收集垃圾,因为它维护对内核的引用。

如果我对它进行了测试,并在内核上调用Dispose,那么我已经杀死了我的内核,并且该应用程序没有更多的DI。

如果我创建一个单独的内核并为QueryProcessor的每个实例注入它,那么Ninject一旦尝试解析具体类型就会丢失异常 - “加载Ninject组件ICache时出错”。显然Ninject不喜欢超过1个内核。

类是否有任何方式可以拥有成员并在收集垃圾之前释放该成员?

1 个答案:

答案 0 :(得分:2)

  

我遇到的问题是,如果我注入Ninject内核,那就是它   表示QueryProcessor类在获取时不会收集垃圾   超出范围,因为它维护对内核的引用。

当没有引用此对象的任何内容时,该对象有资格进行垃圾回收。这个对象引用的其他对象并不重要。所以也许你正在寻找错误位置的内存泄漏。我看到你没有注册任何IKernel事件(这会创建一个从IKernels委托到你的对象的引用)所以如果没有别的东西引用你的QueryProcessor,它应该被垃圾收集。