所以我的工作我的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);
}