我正在开发一个DI/IoC容器OpenNETCF.IoC,与此相关的是一个(合理的)功能请求,要为容器集合中的IDisposable项目添加某种生命周期管理。
我的当前想法是,由于我无法查询对象以查看它是否已被处理,并且我无法获取有关其何时被处理的事件,因此我必须为开发人员希望框架管理的对象创建某种包装器。
现在,可以使用AddNew(为简单起见,我们将假设只有一个重载,并且没有Add)添加对象:
我正在考虑添加一个新的方法(其实是一组方法,但你应该明白):
DisposableWrappedObject看起来像这样:
现在,当通过AddNewDisposable向容器添加项目时,还会添加事件处理程序,以便在通过包装器处置它(从底层集合中)时,框架会将其删除。
我已经实现了这个功能,并且通过了单元测试,但我想知道在哪里可能出错,或者如何使其更加“友好”于使用者。
编辑1
由于有人问到如何使用Disposing事件,这里有一些代码(仅保留重要部分):
我的当前想法是,由于我无法查询对象以查看它是否已被处理,并且我无法获取有关其何时被处理的事件,因此我必须为开发人员希望框架管理的对象创建某种包装器。
现在,可以使用AddNew(为简单起见,我们将假设只有一个重载,并且没有Add)添加对象:
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
由于有人问到如何使用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);
}