C# 强制在StructureMap中创建对象
我们使用的是StructureMap,容器的默认生命周期是每次请求该类型时创建一个新对象。最近,我们开始研究如何为web应用程序中的每个HTTP请求创建嵌套容器。它非常有效,只是嵌套容器的生命周期与常规容器完全不同,因为所有对象都在嵌套容器中成为单例 由于我们在大多数对象创建中使用StructureMap,我们的代码在嵌套容器的生命周期中以神秘的方式中断。有人可能会说这是我们的一个错误,我想这是正确的,因为我们调用C# 强制在StructureMap中创建对象,c#,structuremap,C#,Structuremap,我们使用的是StructureMap,容器的默认生命周期是每次请求该类型时创建一个新对象。最近,我们开始研究如何为web应用程序中的每个HTTP请求创建嵌套容器。它非常有效,只是嵌套容器的生命周期与常规容器完全不同,因为所有对象都在嵌套容器中成为单例 由于我们在大多数对象创建中使用StructureMap,我们的代码在嵌套容器的生命周期中以神秘的方式中断。有人可能会说这是我们的一个错误,我想这是正确的,因为我们调用GetInstance(),即使我们真的希望创建一个新实例。但是我找不到任何方法来
GetInstance()
,即使我们真的希望创建一个新实例。但是我找不到任何方法来绕过StructureMap中的生命周期管理并强制创建(类似于CreateInstance()
而不是GetInstance()
)。我们可以开始实现我们自己的CreateInstance()
方法,但那种感觉就像是重新发明了StructureMap。我们还可以更改工厂以显式地创建对象,但当我们需要以通用方式获取实例(container.GetInstance()
)时,这实际上不起作用
因此,任何关于强制StructureMap创建对象、如何更改嵌套容器中的生命周期、如何将工厂代码更改为更显式地创建实例的建议都将非常有用
我们还可以更改工厂以显式地创建对象,但当我们需要以通用方式获取实例(container.GetInstance()
)时,这实际上不起作用
假设您需要它的地方数量有限,这实际上是可行的:
For<IMyType>().Use(s => new MyType());
For()。使用(s=>newmytype());
这些当然也可能是潜在设计问题的症状,例如需要定义特定于租户的上下文,因此请花一些时间仔细重新考虑您的设计
我们还可以更改工厂以显式地创建对象,但当我们需要以通用方式获取实例(container.GetInstance()
)时,这实际上不起作用
假设您需要它的地方数量有限,这实际上是可行的:
For<IMyType>().Use(s => new MyType());
For()。使用(s=>newmytype());
这些当然也可能是潜在设计问题的症状,例如需要定义特定于租户的上下文,因此请花一些时间仔细重新考虑您的设计。我们也遇到了类似情况,在您的问题下讨论了您的这部分评论:
…我们有一个web应用程序的网站/实例,具体取决于 你是谁,我们连接到你所属的数据库。所以我们想要 每个请求都有一个独立的容器,以避免状态溢出到 不同的系统(用户A从用户B的系统中获取对象) 我正在搜索相同的功能,它应该是多线程安全的。然后我找到了这个链接: 结果可以这样描述: 1) 需求:在您的解决方案中有一个抽象。而不是
StructureMap.ObjectFactory.GetInstance
。。。所有部分都应该调用您的
Factory.GetInstance(type)
(及其提供程序,将调用StructureMap(SM)或更高版本的任何其他IoC提供程序)
2) 如果是这种情况(或者您可以为您的工厂
引入管理器模式,并让您的所有代码独立于SM),我们可以创建两个(或更多)容器
首先是默认值
public class DefaultProfileRegistry : Registry
{
public DefaultProfileRegistry()
{
// whatever calls needed to initialize this registry
SetScans(this); // scan
SetSetterInjection(this); // DI
Profile("DefaultProfile", SetDefaults); // even some common defaults
}
现在,让我们创建一个不同的注册表
public class SpecialProfileRegistry : Registry
{
public SpecialProfileRegistry()
{
DefaultProfileRegistry.SetScans(this); // use part from default
...
Profile("Special", DefaultProfileRegistry.SetDefaults); // common defaults
}
好的,我们有:两个注册表。一个是默认的,第二个是特殊的,可以从中获利并调整部分,或者完全不同
3) 在IFactoryProvider
实施者中注册它们,例如StructureMapFactoryProvider
(SMFP):
5) useespecial
必须在此处提供。和不能依赖IFactoryProvider.GetInstance()
。如果在整个请求处理过程中此值为常量,则正确的IContainer
将为正确的对象提供服务
6) 每个IContainer
都可以有不同的约定、不同的LiefCycle设置。。。即使在注册了数千个插件类型的情况下,此解决方案也提供了非常好的性能,并且是多线程安全的(例如,没有配置文件切换)我们也遇到了类似的情况,在您的问题下讨论了您的这部分评论:
…我们有一个web应用程序的网站/实例,具体取决于
你是谁,我们连接到你所属的数据库。所以我们想要
每个请求都有一个独立的容器,以避免状态溢出到
不同的系统(用户A从用户B的系统中获取对象)
我正在搜索相同的功能,它应该是多线程安全的。然后我找到了这个链接:
结果可以这样描述:
1) 需求:在您的解决方案中有一个抽象。而不是StructureMap.ObjectFactory.GetInstance
。。。所有部分都应该调用您的
Factory.GetInstance(type)
(及其提供程序,将调用StructureMap(SM)或更高版本的任何其他IoC提供程序)
2) 如果是这种情况(或者您可以为您的工厂
引入管理器模式,并让您的所有代码独立于SM),我们可以创建两个(或更多)容器
首先是默认值
public class DefaultProfileRegistry : Registry
{
public DefaultProfileRegistry()
{
// whatever calls needed to initialize this registry
SetScans(this); // scan
SetSetterInjection(this); // DI
Profile("DefaultProfile", SetDefaults); // even some common defaults
}
现在,让我们创建一个不同的注册表
public class SpecialProfileRegistry : Registry
{
public SpecialProfileRegistry()
{
DefaultProfileRegistry.SetScans(this); // use part from default
...
Profile("Special", DefaultProfileRegistry.SetDefaults); // common defaults
}
好的,我们有:两个注册表。一个是默认的,第二个是特殊的,可以从中获利并调整部分,或者完全不同
3) 在IFactoryProvider
实施者中注册它们,例如StructureMapFactoryProvider
(SMFP):
5) useespecial
必须在此处提供。和