代码之家  ›  专栏  ›  技术社区  ›  ctacke

DI:处理IDisposable对象的生命周期

  •  8
  • ctacke  · 技术社区  · 16 年前

    所以我正在开发我的DI/IoC容器 OpenNETCF.IoC 我得到了一个(合理的)特性请求,为容器集合中的IDisposable项添加某种形式的生命周期管理。

    现在可以使用AddNew添加对象(为了简单起见,我们假设只有一个重载,没有Add):

    public TTypeToBuild AddNew<TTypeToBuild>() { ... }
    

    我正在考虑的是添加一种新方法(好吧,这是一组新方法,但您可以了解情况):

    public DisposableWrappedObject<IDisposable> AddNewDisposable<TTypeToBuild>()
        where TTypeToBuild : class, IDisposable
    {
        ...
    }
    

    其中可处置包装对象如下所示:

    public class DisposableWrappedObject<T>
        where T : class, IDisposable
    {
        public bool Disposed { get; private set; }
        public T Instance { get; private set; }
    
        internal event EventHandler<GenericEventArgs<IDisposable>> Disposing;
    
        internal DisposableWrappedObject(T disposableObject)
        {
            if (disposableObject == null) throw new ArgumentNullException();
    
            Instance = disposableObject;
        }
    
        ~DisposableWrappedObject()
        {
            Dispose(false);
        }
    
        public void Dispose()
        {
            Dispose(true);
        }
    
        protected virtual void Dispose(bool disposing)
        {
            lock(this)
            {
                if(Disposed) return;
    
                EventHandler<GenericEventArgs<IDisposable>> handler = Disposing;
                if(handler != null)
                {
                    Disposing(this, new GenericEventArgs<IDisposable>(Instance));
                }
    
                Instance.Dispose();
    
                Disposed = true;
            }
        }
    }
    

    现在,当一个项目通过AddNewDIsposable添加到容器中时,也会添加一个eventhandler,这样当它被释放(通过包装器)时,框架会将其从基础集合中移除。

    事实上,我已经实现了它,并且它正在通过单元测试,但我正在寻找关于这一点可能被打破的意见,或者如何使它对使用它的开发人员更加“友好”。

    编辑1

    由于有一个关于如何使用Disposing事件的问题,下面是一些代码(根据重要内容进行了调整):

    private object AddNew(Type typeToBuild, string id, bool wrapDisposables)
    {
        ....
    
        object instance = ObjectFactory.CreateObject(typeToBuild, m_root);
    
        if ((wrapDisposables) && (instance is IDisposable))
        {
            DisposableWrappedObject<IDisposable> dispInstance = new
                   DisposableWrappedObject<IDisposable>(instance as IDisposable);
            dispInstance.Disposing += new 
                   EventHandler<GenericEventArgs<IDisposable>>(DisposableItemHandler);
            Add(dispInstance as TItem, id, expectNullId);
            instance = dispInstance;
        }
    
        ....
    
        return instance;
    }
    
    private void DisposableItemHandler(object sender, GenericEventArgs<IDisposable> e)
    {
        var key = m_items.FirstOrDefault(i => i.Value == sender).Key;
        if(key == null) return;
        m_items.Remove(key);
    }
    
    1 回复  |  直到 16 年前
        1
  •  3
  •   Community Mohan Dere    9 年前

    我还想知道你是否需要析构函数。假设容器是IDisposable的(比如Unity),您可以实现 Basic Dispose Pattern

    一些可能适用的问题: