为什么在StructureMap中处理Singleton类而不是瞬态

时间:2014-12-04 11:13:59

标签: structuremap structuremap3

在我的应用程序中,我注意到如果我将SM注册表中的一个类标记为Singleton类型,它会被处理掉,但是如果不指定任何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 个答案:

答案 0 :(得分:1)

Singleton生命周期绑定到容器的范围,因此在处理容器时,需要小心处理实现 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()无法执行时会发生什么?在disposableType字段上不会调用Dispose。实际上在这种情况下, ClassWithDisposableTypeDependency 也应该实现IDisposable并处理它的一次性依赖项。

但是有一种更好的方法来处理这种情况。在上述案例中,主要问题是将依赖项的创建推迟到我们真正需要该对象的时刻。我们可以通过多种方式实现这一目标:func,lazy,factory等。这是使用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

希望这有帮助!