2009-12-22 73 views
0
  • 我们有一个使用IoC容器传递给构造函数的接口
  • 我们有多个类来实现这个接口。

问题是,有些(不是全部)实现需要清理,最好使用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

什么时候需要调用Dispose?执行工作或应用程序关闭后?如果后者,您的IoC容器不支持这种清理?在Java和Spring IoC容器中,您的实现将实现Spring的一次性接口,并且容器将在关闭期间调用dispose方法。

+0

我在发生错误时专门清理了一些事件处理程序。我基本上想关闭一些在后台运行的类。我想可以使用自定义的生命周期,让我手动关闭类的按需。我正在使用Structuremap。 – 2009-12-22 16:14:03

1

有什么不对下面?

interface IBar { void DoWork(); } 
class Foo : IBar, IDisposable { // details, implements Dispose } 
class Foo2 : IBar { // details, no Dispose } 
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

奇怪的问题。如果您关注的是具体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不会继承或暴露任何这样的方法 - 我的意思是,考虑你是否处置了一个重要的单例服务!这会有多尴尬?

那么谁来负责注入组件的生命周期呢?那么容器当然是!如前所述,大多数容器将检查组件实现为IDisposable实现[也另一个理由使用标准CLR定义的接口],和将调用Dispose当它确定部件已经到达其寿命的终点。所以SomeDisposableBusinessImplementation最终会妥善处置。 :)


温莎城堡

温莎城堡IoC容器的轨道,并保持它创建的所有实例的引用。它使用反射来确定实例是否“一次性”,然后在实例的生命周期完成时调用Dispose()。对于长寿命的物体,这是容器被丢弃的时候。对于短暂的短暂对象,这是消费者*明确调用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。

+0

你通常如何告诉你的IoC容器,你已经完成了一堂课? 假设应用程序有许多类使用的长时间运行的文件写入接口。如果我想要一个关闭文件的按钮,我该怎么做?我需要以某种方式告诉IoC容器,但我不知道该怎么做。 定制生命周期/生活方式? – 2009-12-22 16:33:56

+0

我看到一种方法可以和Windsor做到,但不是结构图。 – 2009-12-22 16:41:34

+0

处理查询... [即谷歌搜索结构图] ...将更新一次编译。 – 2009-12-22 19:01:48

相关问题