2013-04-12 41 views
0

我有一個問題,試圖讓singleton生命週期在StructureMap中與自定義約定一起使用。Singleton with ASP.NET MVC中的StructureMap自定義約定4

基本上我有一個包含我想成爲一個使得它在應用程序啓動時創建一次字典定製註冊表類型的類。

我創建了一個自定義的公約將看到一個類的屬性並確定類是否應該是HttpContextScoped辛格爾頓

的問題是,當我與Visual Studio調試器中運行應用程序的對象的構造應該是一個單身被調用每次加載網頁,而不是如我所料發生一次時間。它看起來像對象表現爲HttpContextScoped代替辛格爾頓

這裏還有一些細節:

StructuremapMvcapp_start文件夾

public static class StructuremapMvc 
    { 
     public static void Start() 
     { 
      IContainer container = IoC.Initialize(); 
      DependencyResolver.SetResolver(new StructureMapDependencyResolver(container)); 
      GlobalConfiguration.Configuration.DependencyResolver = new StructureMapDependencyResolver(container); 
     } 
    } 

的Ioc

公共靜態初始化的IContainer()

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 

回答

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>();