C# 创建StructureMap容器的克隆
我正在开发一个MVVM应用程序。它有一些整个应用程序需要的对象(单个实例),也有一些只有某些窗口/控件需要的对象(每个控件一个实例) 我想将StructureMap容器配置为包含所有应用程序实例,就像普通的一样。打开窗口/控件时,我希望创建容器的克隆,并将该控件所需的对象添加到克隆的配置中。克隆应扩展原始容器,并应包含相同的配置和实例 这可以用StructureMap实现吗?(我正在查看嵌套容器,但我不确定这是否是我想要的) 更多详细信息… 这里有一个测试可以显示这种行为。首先是标准材料:C# 创建StructureMap容器的克隆,c#,mvvm,structuremap,C#,Mvvm,Structuremap,我正在开发一个MVVM应用程序。它有一些整个应用程序需要的对象(单个实例),也有一些只有某些窗口/控件需要的对象(每个控件一个实例) 我想将StructureMap容器配置为包含所有应用程序实例,就像普通的一样。打开窗口/控件时,我希望创建容器的克隆,并将该控件所需的对象添加到克隆的配置中。克隆应扩展原始容器,并应包含相同的配置和实例 这可以用StructureMap实现吗?(我正在查看嵌套容器,但我不确定这是否是我想要的) 更多详细信息… 这里有一个测试可以显示这种行为。首先是标准材料: [T
[Test]
public void Mupp()
{
var parent = new Container(x =>
{
x.For<IMyServiceAgent>().Singleton().Use<MyServiceAgent>();
});
var parentServiceAgent = parent.GetInstance<IMyServiceAgent>();
我想用本地对象扩展配置
scoped1.Configure(x =>
{
x.For<IMyPresenter>().Singleton().Use<MyPresenter>();
});
var scopedPresenter1 = scoped1.GetInstance<IMyPresenter>();
scoped1.GetInstance<IMyPresenter>().ShouldBeTheSameAs(scopedPresenter1);
scoped1.Configure(x=>
{
x、 For().Singleton().Use();
});
var scopedPresenter1=scoped1.GetInstance();
scoped1.GetInstance().ShouldBeTheSameAs(scopedPresenter1);
创建容器的第二个克隆不会与第一个克隆共享实例(或配置)
IContainer scoped2 = CreateCloneOf(parent);
scoped2.Configure(x =>
{
x.For<IMyPresenter>().Singleton().Use<MyPresenter>();
});
scoped2.GetInstance<IMyPresenter>().ShouldNotBeTheSameAs(scopedPresenter1);
IContainer scoped2=CreateCloneOf(父级);
scoped2.Configure(x=>
{
x、 For().Singleton().Use();
});
scoped2.GetInstance().不应为ESAMEAS(scopedPresenter1);
作用域容器中配置的内容不应在父容器中
parent.GetInstance<IMyPresenter>(); // Should throw
parent.GetInstance();//应该扔
应该可以从作用域容器创建作用域容器
IContainer moreScoped = CreateCloneOf(scoped1);
moreScoped.GetInstance<IMyPresenter>().ShouldBeTheSameAs(scopedPresenter1);
}
IContainer moreScoped=CreateCloneOf(scoped1);
moreScoped.GetInstance().ShouldBeTheSameAs(scopedPresenter1);
}
根据您的问题判断,您正在寻找的似乎是嵌套容器
您可以通过创建嵌套容器来实现目标(嵌套容器是适合短期操作的容器副本,对嵌套容器的任何更改都不会反映在从中克隆的容器中-)
一旦您拥有了嵌套容器,您就可以为要在其中使用嵌套容器的模块所需的新操作添加StructureMap注册表
像这样:
设置:
public void ApplicationBootstrap()
{
IContainer container = StructureMapCoreSetup.Initialise();
container.Configure(c =>
{
c.IncludeRegistry<DefaultRegistry>();
});
}
public class ApplicationModule
{
public ApplicationModule(IContainer container)
{
childContainer = container.GetNestedContainer();
childContainer.Configure(x =>
{
x.AddRegistry<ModuleSpecificRegistry>();
});
}
}
public void ApplicationBootstrap()
{
IContainer container=StructureMapCoreSetup.Initialise();
container.Configure(c=>
{
c、 IncludeRegistry();
});
}
用法:
public void ApplicationBootstrap()
{
IContainer container = StructureMapCoreSetup.Initialise();
container.Configure(c =>
{
c.IncludeRegistry<DefaultRegistry>();
});
}
public class ApplicationModule
{
public ApplicationModule(IContainer container)
{
childContainer = container.GetNestedContainer();
childContainer.Configure(x =>
{
x.AddRegistry<ModuleSpecificRegistry>();
});
}
}
公共类应用程序模块
{
公共应用程序模块(IContainer容器)
{
childContainer=container.GetNestedContainer();
配置(x=>
{
x、 AddRegistry();
});
}
}
对嵌套容器所做的任何更改都不会反映在任何其他容器中的任何容器中(除非您创建了嵌套容器的嵌套实例),并且可以在使用完该容器后处置该容器
希望这就是你所寻找的,或者至少为你指明了正确的方向 我不确定这是否可能,但这不是重点。如果需要,则整个应用程序不应该有多个容器。如果在运行时需要类的实例,则应使用而不是DI容器来创建它们。@NightOwl888对于web应用程序,我同意。在桌面应用程序中,窗口/控件可以是自己的世界。我现在使用一个工厂(每个复杂的控件一个),但希望能够用IoC容器替换其中的所有锅炉板。但是我会接受你的建议,看看是否有什么我可以做的不同。答案很好,但我不认为你正在配置/使用嵌套容器。它应该是
var childContainer=container.GetNestedContainer();Configure(x=>…
发现得很好!感谢您指出这一点,我已经更新了我的答案。