0

我正在學習MVC2中的最佳實踐,我正在關閉Codeplex的「誰可以幫我」項目(http://whocanhelpme.codeplex.com/)的副本。其中,他們使用Castle Windsor作爲他們的DI容器。我試圖做的一個「學習」任務是將此項目中的此子系統轉換爲使用StructureMap。從溫莎城堡轉換到MVC2項目中的StructureMap

基本上,在Application_Start(),代碼消息向上一個Windsor容器。然後,它通過多個組件,使用MEF,在ComponentRegistrar.cs:

public static class ComponentRegistrar 
{ 
    public static void Register(IContainer container) 
    { 
     var catalog = new CatalogBuilder() 
          .ForAssembly(typeof(IComponentRegistrarMarker).Assembly) 
          .ForMvcAssembly(Assembly.GetExecutingAssembly()) 
          .ForMvcAssembliesInDirectory(HttpRuntime.BinDirectory, "CPOP*.dll") // Won't work in Partial trust 
          .Build(); 

     var compositionContainer = new CompositionContainer(catalog); 

     compositionContainer 
      .GetExports<IComponentRegistrar>() 
      .Each(e => e.Value.Register(container)); 
    } 
} 

,並在有IComponentRegistrar界面會得到其註冊()方法運行任何程序集的任何類。

例如,控制器註冊商註冊()方法的實現主要是:

public void Register(IContainer container) 
{ 
    Assembly.GetAssembly(typeof(ControllersRegistrarMarker)).GetExportedTypes() 
      .Where(IsController) 
      .Each(type => container.AddComponentLifeStyle( 
          type.Name.ToLower(), 
          type, 
          LifestyleType.Transient)); 
} 

private static bool IsController(Type type) 
{ 
    return typeof(IController).IsAssignableFrom(type); 
} 

希望,我不是屠宰WCHM太多。我想知道如何用StructureMap來做這件事?我假設我使用Configure(),因爲Initialize()會在每次調用時重置容器?或者,是一個完全不同的方法?我是否需要基於MEF的程序集掃描,用於查找所有註冊器並運行每個Register(),還是在StructureMap的Scan()中有類似的東西?

回答

1

覺得髒,回答我的問題,但我做了以下內容:

public class ControllerRegistrar : IComponentRegistrar 
    { 
     public void Register(IContainer container) 
     { 
      container.Configure(x => 
      { 
       x.Scan(scanner => 
       { 
        scanner.Assembly(Assembly.GetExecutingAssembly()); 
        scanner.AddAllTypesOf<IController>().NameBy(type => type.Name.Replace("Controller", "")); 
       }); 
      }); 

     } 
    } 

我不是100%確定這是正確的,但它的工作原理。主要從this StructureMap doc page的「按名稱註冊類型」部分拉出。

1

查看StructureMap的註冊表(http://structuremap.github.com/structuremap/RegistryDSL.htm)。要控制生命週期使用類似於:

For<ISomething>().Use<Something>().LifecycleIs(new SingletonLifecycle()); 

(瞬態是默認值)。

當你引導的容器,你可以說:

ObjectFactory.Initialize(c => c.Scan(s => { 
    s.WithDefaultConventions(); 
    s.LookForRegistries(); 
} 
+0

據我所知,我只能調用Initialize()一次。因此,ObjectFactory.Initialize()必須與ComponentRegistrar.Register()等價。 Scan()將取代MEF代碼?而不是IComponentRegistrar的Register()的實現,我只是創建多個Registry類?最後,Scan()會掃描多個程序集? MEF代碼將掃描多個項目/程序集。 – alphadogg 2010-05-07 11:42:55

+0

我決定保留MEF,以便讓我可能希望Register()不僅僅是將項目放入StructureMap容器​​中。這需要我在這個問題的答案中的代碼。 – alphadogg 2010-05-10 03:10:22