我们处于类似情况,在您的问题下谈论您评论的这一部分:
...我们有一个 Web 应用程序的网站/实例,并且取决于
你是谁,我们连接到你所属的数据库。所以我们想要
每个请求一个隔离的容器,以避免状态溢出
不同的系统(用户 A 从用户 B 的系统中获取对象)...
我正在寻找相同的功能,它应该是多线程安全的。然后我找到了这个链接:
StructureMap: Multithreaded env. No default instance defined for PluginFamily
结果可以这样描述:
1) 要求:您的解决方案中有一个抽象。而不是StructureMap.ObjectFactory.GetInstance... 所有部分都应该调用你的
Factory.GetInstance(type)
(及其提供者,将调用 StructureMap (SM) 或稍后调用任何其他 IoC 提供者)
2) 如果是这种情况(或者您可以为您的Factory 引入例如 Manager 模式,并让您的所有代码缩进 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
}
现在让我们创建一个不同的Registry
public class SpecialProfileRegistry : Registry
{
public SpecialProfileRegistry()
{
DefaultProfileRegistry.SetScans(this); // use part from default
...
Profile("Special", DefaultProfileRegistry.SetDefaults); // common defaults
}
好吧,我们有:两个Registry。一是默认,二是特殊可以从中获利并调整一部分,或者完全不同...
3) 在IFactoryProvider 实现者中注册它们,例如StructureMapFactoryProvider (SMFP):
public partial class StructureMapFactoryProvider : IFactoryProvider
{
private static readonly IContainer Special;
static StructureMapFactoryProvider()
{
// 1) the default registry container
ObjectFactory.Initialize(x =>
{
x.UseDefaultStructureMapConfigFile = false;
// Defaults
x.IncludeRegistry<DefaultProfileRegistry>();
});
ObjectFactory.Container.SetDefaultsToProfile("DefaultProfile");
// 2) and now register the other(s)
Special = new StructureMap.Container(new SpecialProfileRegistry());
Special.SetDefaultsToProfile("Special");
}
好吧,现在,当我们的 SMFP 第一次被触摸时,所有的容器都被实例化了......
4) 最后在IFactoryProvider.GetInstance() 中,我们可以决定使用什么
object IFactoryProvider.GetInstance(Type type)
{
var useSpecial = ... // get the information to decide
if (useDefault)
{
return Special.GetInstance(type);
}
else
{
return ObjectFactory.GetInstance(type);
}
5) useSpecial 必须在这个地方以某种方式可用。并且不得依赖IFactoryProvider.GetInstance()。如果在整个请求处理过程中此值为 const,则正确的 IContainer 将提供正确的对象。
6) 这些IContainer 中的每一个都可能有不同的约定、不同的LiefCycle 设置...即使在某些情况下,也有成千上万的PluginTypes 注册,这个解决方案提供了非常好的性能并且是多线程安全的(例如没有配置文件切换)