0

我在尝试使单例生命周期与StructureMap 中的自定义约定一起工作时遇到问题。

基本上我有一个自定义注册表类型类,其中包含一个我想成为单例的字典,以便在应用程序启动时创建一次。

我创建了一个自定义约定,它将查看类的属性并确定该类是否应该是HttpContextScopedSingleton

问题是,当我使用 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);
        }
    }

国际奥委会

公共静态 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
4

1 回答 1

1

这个问题似乎很老了,但无论如何我都会尝试回答它,因为可能还有其他人遇到了与结构图相同的问题。在某些情况下,单例实例是“每个实例”创建的,指的是它们被注入的实例。这意味着当它们被注入到其他地方时,您可以拥有不同的“单例”实例。我个人在 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>();
于 2013-08-03T22:32:24.093 回答