DI:处理IDisposable的对象的生活(DI: Handling Life of IDispo

2019-08-17 21:24发布

所以我的工作我的DI / IOC容器OpenNETCF.IoC和我有一个(合理)的功能要求添加某种形式的生命周期管理在容器的IDisposable收藏的物品。

我目前的想法是,既然我无法查询的对象,以确定它已经被设置了,我不能得到,当它被布置为一个事件,我必须创建一个开发者想要的对象某种形式的包装器该框架来管理。

现在可以用的AddNew(为简单起见,我们假定只有一个超载和不存在添加)添加对象:

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

我正在考虑是增加了新的方法(以及它们的组,但你得到的图片):

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

凡DisposableWrappedObject看起来是这样的:

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容器,也增加了一个事件处理程序,这样,当它得到处理(通过包装)的框架,从底层集合中删除。

其实,我有这样的实现,它的传球单元测试,但我正在寻找的意见在哪里,这可能被打破,不然怎么可能会变得更加“友好”的消费开发商。

编辑1

由于没有关于如何使用处置事件的问题,这里的一些代码(修剪到什么是重要的):

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);
}

Answer 1:

也许我失去了一些东西,但为什么新的方法添加到API? 当一个对象被添加到容器中,可以铸态来检查它是否是IDisposable接口,如果是妥善处理这个问题。

我也想知道,如果你需要的析构函数。 假设该容器是IDisposable接口(如统一的),你可以只实现基本Dispose模式 ,节省了大量GC开销。

一些问题可能适用:

  • 你如何调和IDisposable接口和IOC?
  • 控制和RAII的反转可以一起玩?


文章来源: DI: Handling Life of IDisposable Objects