0

在我的应用程序中,我注意到如果我将 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();              

        }

    }
}
4

1 回答 1

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() 不被执行时会发生什么?Dispose 不会在disposableType 字段上调用。实际上在这种情况下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

希望这可以帮助!

于 2014-12-08T13:07:59.337 回答