2014-12-04 45 views
0

在我的应用程序中,我注意到如果我将SM注册表中的类标记为Singleton类型,它将被处理掉,但是如果不指定任何Singleton它不会被处理掉。 这是为什么?为什么在StructureMap中处理Singleton类而瞬变不是

public class IoC 
{ 
    public static IContainer Init() 
    { 
     var container = new Container(x => 
     { 
      x.Scan(s => { 
       s.TheCallingAssembly(); 
       s.AssembliesFromApplicationBaseDirectory(); 
       s.WithDefaultConventions();     
      }); 

      // disposed is called on this class but not if .Singleton() is removed 
      x.For<IMyService>().Singleton(); 
     }); 

     return container; 
    } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     using (var container = IoC.Init()) 
     { 
      var theStory1 = container.GetInstance<MyService>(); 
      theStory1.TheMethod();    

     } 

    } 
} 

回答

1

辛格尔顿的生命周期被绑定到容器的范围从而处置容器时,需要注意处置实施IDisposable的所有单身人士。对于瞬变和其他生命周期,如HttpContextScoped开发人员在不再需要它们时手动配置它们。

暂时性的一次性用品在应该如何处理方面有点棘手。想象下面这样的情况:

public class ClassWithDisposableTypeDependency 
{ 
    private readonly ISampleDisposable disposableType; 

    public ClassWithDisposableTypeDependency(ISampleDisposable disposableType) 
    { 
     this.disposableType = disposableType; 
    } 

    public void SomeAction() 
    { 
     using (this.disposableType) 
     { 
      this.disposableType.DoSomething(); 
     } 
    } 
} 

当SomAction()不会被执行时会发生什么? DisposeType字段不会调用Dispose。实际上,在这种情况下,ClassWithDisposableTypeDependency还应该实现IDisposable并处理其一次性依赖项。

但是有更好的方法来处理这种情况。在提到的情况下,主要的问题是推迟创建依赖到我们确实需要这些对象的时刻。我们可以在很多方面达到这个目标:func,懒惰,工厂等。这里是使用func的可能解决方案。

public class ClassWithDisposableTypeFuncDependency 
{ 
    private readonly Func<ISampleDisposable> disposableTypeFactory; 

    public ClassWithDisposableTypeFuncDependency(Func<ISampleDisposable> disposableTypeFactory) 
    { 
     this.disposableTypeFactory = disposableTypeFactory; 
    } 

    public void SomeAction() 
    { 
     var disposable = this.disposableTypeFactory(); 

     using (disposable) 
     { 
      disposable.DoSomething(); 
     } 
    } 
} 

这是我们需要设置它在StructureMap:

var container = new Container(c => c.For<ISampleDisposable>().Use<SampleDisposable>()); 

var clazz = container.GetInstance<ClassWithDisposableTypeFuncDependency>(); 

clazz.SomeAction(); // dependency is created and disposed 

希望这有助于!

+0

我认为这是有道理的,但我注意到嵌套容器**做**处置。所以我现在想知道为什么StructureMap可以跟踪嵌套容器中的瞬态对象而不是根容器? – user183872 2014-12-11 09:49:06

+0

@ user183872 - 我忘了提及嵌套容器。 Jeremy D. Miller在这里解释了为什么嵌套容器是这样设计的以及如何使用它 - http://structuremap.github.io/the-container/nested-containers/ – LetMeCodeThis 2014-12-11 11:17:31

相关问题