对于未注册的具体类型,默认为始终唯一

本文关键字:默认 唯一 类型 注册 于未 | 更新日期: 2023-09-27 17:54:24

考虑以下代码

var container = new Container();
var nested = container.GetNestedContainer();
var f1 = nested.GetInstance<Foo>();
var f2 = nested.GetInstance<Foo>();
var result = f1 == f2; //I want result to be false

我不想注册每个可以注入的具体类型但我希望它们对于每个构造函数注入或对GetInstance的调用都是唯一的

更新:

嗯,我必须使用NestedContainers错误?我想做的是为程序的子部分创建一个"子"容器(它是一个WPF客户端,所以子部分可以是一个像弹出窗口或其他什么的子模型)。子模型可以有自己的子模型或服务,它们可以是具体的且未注册的,也可以是已注册的接口。具体的类型我根本不想登记。我想让接口默认为Structuremap的AlwaysUnique,但在我的世界里,这就是瞬态生存期。对于99.9%的类型,我希望总是唯一的,0.01%的类型,我希望在嵌套容器的生命周期内使用相同的引用。也许这个用例不适合嵌套容器?

编辑:一个典型的用例是事件聚合仅在程序的一部分,如弹出模型和它的子

对于未注册的具体类型,默认为始终唯一

如果我正确理解您的问题,我们可以明确指定 ILifecycle 为瞬态(每次请求时重新创建): TransientLifecycle

var container = new Container(x =>
{
    x.For<IMyService>(new StructureMap.Pipeline.TransientLifecycle())
     .Use<MyService>();
});

中解析
var f1 = container.GetInstance<IMyService>();
var f2 = container.GetInstance<IMyService>();
Assert.IsTrue(f1 != f2);

几乎同样可以用我们的自定义约定实现:

public class MyConvention : DefaultConventionScanner
{
    public override void Process(Type type, Registry registry)
    {
        base.Process(type, registry);
        // here we shold do some evaluation what to map
        // for example
        // just classes wich are not abstract 
        var skipType = type.IsAbstract
                       || !type.IsClass;
        if (skipType)
        {
            return;
        }
        // here we do the magic
        // register each type with transient Lifecycle
        registry.For(type)
            .LifecycleIs(new StructureMap.Pipeline.TransientLifecycle())
            .Use(type);
    }
}

可以这样使用来得到相同的结果

var container = new Container(x =>
{
    x.Scan(s =>
    {
        s.AssemblyContainingType<MyService>();
        s.Convention<MyConvention>();
    });
}
var f1 = container.GetInstance<MyService>();
var f2 = container.GetInstance<MyService>();
Assert.IsTrue(f1 != f2);