我在尝试让 singleton 生命周期与StructureMap中的自定义约定一起使用时遇到问题。
基本上我有一个自定义的注册表类型类,它包含一个我想成为单例的字典,以便在启动应用程序时创建一次。< / p>
我创建了一个自定义约定,它会查看某个类的属性,并确定该类是否应为 HttpContextScoped 或辛格尔顿
问题是,当我使用Visual Studio调试器运行应用程序时,应该是一个单例的对象的构造函数每次都会被调用加载网页而不是像我预期的那样发生一次。看起来该对象表现为 HttpContextScoped 而不是 Singleton 。
以下是一些细节:
app_start 文件夹中StructuremapMvc 类
public static class StructuremapMvc
{
public static void Start()
{
IContainer container = IoC.Initialize();
DependencyResolver.SetResolver(new StructureMapDependencyResolver(container));
GlobalConfiguration.Configuration.DependencyResolver = new StructureMapDependencyResolver(container);
}
}
Ioc 类
public static IContainer Initialize()
ObjectFactory.Initialize(x =>
{
x.Scan(scan =>
{
scan.TheCallingAssembly();
scan.AssemblyContainingType<IConfigManager>();
scan.WithDefaultConventions();
scan.Convention<CustomConvention>();
});
CustomConvention : IRegistrationConvention
public void Process(Type type, Registry registry) public void Process(Type type, Registry registry)
{
var attributes = type.GetCustomAttributes(false);
if (attributes.Length > 0)
{
if (attributes[0] is SingletonAttribute)
{
registry.For(type).Singleton();
}
else if (attributes[0] is HttpContextScopedAttribute)
{
registry.For(type).HttpContextScoped();
}
}
}
[Singleton]
public class MyRegistry : IMyRegistry
答案 0 :(得分:1)
这个问题似乎已经很老了,但无论如何我都会回答它,因为可能还有其他人遇到了与Structure map相同的问题。在某些情况下,单个insance是“每个实例”创建的,指的是它们被注入的实例。这意味着当它们被注入其他地方时,你可以拥有不同的“singleton”实例。我个人在MVC应用程序中看到了WEBAPI的这种行为。
我能使其成为“真正的”全局单例的唯一方法是使用具有特定类型参数的通用接口来区分要使用的不同类型:
public interface ITest<T>
{
}
public class Test1 : ITest<int>
{
}
public class Test2 : ITest<string>
{
}
Scan(x =>
{
x.TheCallingAssembly();
x.IncludeNamespace("MvcApplication1");
x.ConnectImplementationsToTypesClosing(typeof(ITest<>))
.OnAddedPluginTypes(a => a.LifecycleIs(InstanceScope.Singleton));
});
我知道这不像上面描述的方法那样优雅也不实用,但至少它按预期工作。其他有效的方法是一对一地进行标准映射:
For<ISingleton>().Singleton().Use<Singleton>();