2011-12-27 48 views
3

我目前通過此代碼段工作從設計模式的書:如何使用StructureMap爲靜態類指定setter注入?

public static class DomainEvents 
{ 
    public static IDomainEventHandlerFactory DomainEventHandlerFactory { get; set; } 

    public static void Raise<T>(T domainEvent) where T : IDomainEvent 
    { 
     DomainEventHandlerFactory.GetDomainEventHandlersFor(domainEvent).ForEach(h => h.Handle(domainEvent)); 
    } 
} 

這本書以接線,DomainEvents,而這個特定的代碼段是負責讓我通過對DomainEvents的Raise方法引發一個事件。

這裏是我的引導程序文件中的代碼:

public class ControllerRegistry : Registry 
{ 
     public ControllerRegistry() 
     { 
      ForRequestedType<IDomainEventHandlerFactory>().TheDefault.Is.OfConcreteType<StructureMapDomainEventHandlerFactory>(); 
      ForRequestedType<IDomainEventHandler<OrderSubmittedEvent>>().AddConcreteType<OrderSubmittedHandler>(); 
     } 
    } 

當我去從我的服務層訪問DomainEvents.Raise(在這個例子中,我提高了OrderSumittedEvent),DomainEventsnull(當它應該通過StructureMap設置):

public class OrderService 
{ 
    public void Create(Order order) 
    { 
     DomainEvents.Raise(new OrderSubmittedEvent() { Order = order }); 
    } 
} 

除非我明確設置DomainEvents.DomainEventHandlerFactory手工StructureMapDomainEventHandlerFactory這樣的:

public class OrderService 
{ 
    public void Create(Order order) 
    { 
     // this is the manual assignment I have to make into the DomainEventHandlerFactory of 
     // the static DomainEvents class. Basically, this is what StructureMap should take care 
     // of for me, but is not. 
     DomainEvents.DomainEventHandlerFactory = new StructureMapDomainEventHandlerFactory(); 

     DomainEvents.Raise(new OrderSubmittedEvent() { Order = order }); 
    } 
} 

下面是StrucutureMap的使用.WhatDoIHave()輸出,並且看起來StructureMap確實有StructureMapDomainEventHandlerFactory配置的實例IDomainEventHandlerFactory類型。下面是轉儲:

================================================================================================================================================================================================================================================================================================================================================================================================ 
PluginType                     Name                               Description                                       
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 
Func`1<TResult> (Func`1<TResult>)                                                                                        
Scoped as: Transient 

                         311731d7-60c7-46de-9ef4-24608f21df04                                                                 
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 
IDomainEventHandlerFactory (DE.Infrastructure.Domain.Events.IDomainEventHandlerFactory)  dbcb010c-fa92-4137-85b8-161ab17c2c98                       Configured Instance of DE.Infrastructure.Domain.Events.StructureMapDomainEventHandlerFactory, DE.Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null 
Scoped as: Transient 

                          dbcb010c-fa92-4137-85b8-161ab17c2c98                       Configured Instance of DE.Infrastructure.Domain.Events.StructureMapDomainEventHandlerFactory, DE.Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null 
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 
IDomainEventHandler`1<OrderSubmittedEvent> (IDomainEventHandler`1<OrderSubmittedEvent>)  DE.Services.DomainEventHandlers.OrderSubmittedHandler, DE.Services, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null  Configured Instance of DE.Services.DomainEventHandlers.OrderSubmittedHandler, DE.Services, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null      
Scoped as: Transient 

                          DE.Services.DomainEventHandlers.OrderSubmittedHandler, DE.Services, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null  Configured Instance of DE.Services.DomainEventHandlers.OrderSubmittedHandler, DE.Services, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null      
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 
IContainer (StructureMap.IContainer)              e24f9e45-caaf-48b6-89f7-d8125310102a                       Object: StructureMap.Container                                  
Scoped as: Transient 

                          e24f9e45-caaf-48b6-89f7-d8125310102a                       Object: StructureMap.Container                                  
================================================================================================================================================================================================================================================================================================================================================================================================ 

我用StructureMap,但我沒有使用Setter注入,也沒有我不得不處理使用StructureMap靜態類(如果這甚至是有道理的),所以我有點失落,爲什麼這段代碼不起作用。

是否有可能像這樣使用Setter Injection與類的靜態實現? 我沒有正確使用StructureMap嗎? 應該StructureMap負責創建DomainEvents類作爲一個單身人士,我可以擺脫靜態實施?

謝謝, 邁克

+2

這是什麼結論呢? – sawe 2013-05-06 05:26:53

回答

0

是否有可能使用Setter注入了靜態實現像這樣一類的?

號只可能與可創建類。我沒有使用StructureMap正確

是誰?

你不是。依賴注入處理創建並提供實例。根據定義,靜態類在代碼中是不可創建的,因此是不可注入的。

應該由StructureMap負責創建DomainEvents類作爲一個Singleton,並且我可以擺脫靜態實現嗎?

它看起來像這個設計的核心功能是使用一個單一的實例,所以事件只能被觸發一次。我不確定你要設計什麼樣的設計模式,但在很多情況下,你可以用Action<T>Func<T>替代事件,如果你正確使用單身生活方式,你可以註冊一個可以在所有類中共享的單一實例比訴諸靜態類。

如果是絕對必需的靜態事件,你可以在你的應用程序啓動代碼通過拆分實例,並手動設置它,你已經完成了你的註冊碼(在你的composition root)後注入IDomainEventHandlerFactory的一個實例。

// Provide the DI container with configuration 
var container = DIConfig(); 

// Set the static event 
DomainEvents.DomainEventHandlerFactory = container.Resolve<IDomainEventHandlerFactory>(); 

爲了確保您的應用程序不通過調用它一次以上,或將其設置之前使用它濫用制定者,你可以把一些後衛條款在靜態類。

public static class DomainEvents 
{ 
    private static IDomainEventHandlerFactory domainEventHandlerFactory; 

    public static IDomainEventHandlerFactory DomainEventHandlerFactory 
    { 
     get 
     { 
      return domainEventHandlerFactory; 
     } 
     set 
     { 
      if (value == null) 
       throw new ArgumentNullException("value"); 
      if (domainEventHandlerFactory != null) 
       throw new ArgumentException("DomainEventHandlerFactory is already set and cannot be set again."); 
      domainEventHandlerFactory = value; 
     } 
    } 

    public static void Raise<T>(T domainEvent) where T : IDomainEvent 
    { 
     ThrowIfNotInitialized() 
     DomainEventHandlerFactory.GetDomainEventHandlersFor(domainEvent).ForEach(h => h.Handle(domainEvent)); 
    } 

    private static void ThrowIfNotInitialized() 
    { 
     if (domainEventHandlerFactory == null) 
     { 
      throw new MvcSiteMapException("Not initialized. You must set DomainEventHandlerFactory at application start."); 
     } 
    } 
} 
相關問題