问题是,需要清理一些(并非所有)实现,最好使用IDisposable接口。
由于并非所有实现都需要“Dispose”方法,所以我是否还要包含它(我意识到我实际上并没有实现IDisposable,这只是一个例子)?对我来说,似乎知道接口实际实现的类应该知道如何清理这些对象。但是,这是IoC容器,我没有看到任何优雅的方式来通知它在它创建的特定类上调用清理。
interface IBar
{
void DoWork();
void Dispose(); //Not all implementations need this
}
class Foo : IBar
{
public void DoWork()
{
//implementation 1
}
public void Dispose()
{
//cleanup, which needs to be called
}
}
class Foo2 : IBar
{
public void DoWork()
{
//implementation 2
}
public void Dispose()
{
//No cleanup needed in this implementation
}
}
答案 0 :(得分:3)
您可以在需要它的人身上实现IDisposable然后执行此操作:
interface IBar
{
void Bar();
}
class Foo : IBar
{
public void Bar() { }
}
class Foo2 : IBar, IDisposable
{
public void Bar() {}
public void Dispose() {}
}
class Program
{
static void Main(string[] args)
{
foreach (IBar bar in new IBar[] { new Foo(), new Foo2() })
{
bar.Bar();
IDisposable disp = bar as IDisposable;
if (disp != null)
{
disp.Dispose();
}
}
}
}
答案 1 :(得分:1)
以下是什么问题?
interface IBar { void DoWork(); }
class Foo : IBar, IDisposable { // details, implements Dispose }
class Foo2 : IBar { // details, no Dispose }
答案 2 :(得分:1)
奇怪的问题。如果您的关注点是IDisposable
,那么大多数容器都会检查实现,如果它包含IDisposable
的实现,则容器会在释放实例时自动调用Dispose ()
。
所以,
// pure clean business interface. no dispose member
public interface ISomeBusinessInterface { }
// an implementation that does not require any 'disposing'
// and implements *only* business interface
public class SomeBusinessImplementation :
ISomeBusinessInterface
{
}
// an implementation that contains heavy resources and
// requires 'disposing'
public class SomeDisposableBusinessImplementation :
ISomeBusinessInterface,
IDisposable
{
}
// a typical consumer. no knowledge of instance life-cycle
public class SomeConsumer
{
// injector constructor
public SomeConsumer (ISomeBusinessInterface business) { }
}
您的消费者应该不了解注入组件的生命周期,并且不以任何形式或形式对其负责。从这个角度来看,ISomeBusinessInterface
没有继承或暴露任何这样的Dispose
方法是有意义的 - 我的意思是,考虑一下你是否处理了一个重要的单例服务!那会有多么令人尴尬?
那么谁负责注入组件的生命周期?好吧,容器当然是!如前所述,大多数容器将检查组件实现以查找IDisposable
的实现[也是使用标准CLR定义的接口的另一个原因],并在确定组件已达到其结束时调用Dispose
生活。所以SomeDisposableBusinessImplementation
最终会被妥善处理掉。 :)
Castle Windsor
Castle Windsor IoC容器跟踪并维护对其创建的所有实例的引用。它使用反射来确定实例是否为“一次性”,然后在实例的生命周期完成时调用Dispose ()
。对于长寿命物体,这是在处置容器时。对于瞬态短期对象,这是消费者*。{/ p>显式调用Release (object)
的时间
* =这提出了一个重点,瞬态对象应该通过显式调用Resolve<T> ()
获取,并通过显式调用Release (object)
释放。隐式注入瞬态类可能会导致内存泄漏!
<强> StructureMap 强>
StructureMap IoC container does not track and maintain references to transient instances.这几乎意味着对象生命周期管理有点复杂+。这对于短暂的短期对象非常有用,因为不需要额外的簿记except the usual。但是,对于长寿命对象,您必须extend the framework, reflect, and dispose of instances yourself。
+ =复杂的imo。
答案 3 :(得分:0)
什么时候需要调用Dispose?执行工作或应用程序关闭后?如果是后者,你的IoC容器不支持这样的清理吗?在Java和Spring IoC容器中,您的实现将实现Spring的一次性接口,容器将在关闭期间调用dispose方法。