2011-12-27 10 views
3
私は現在、デザインパターンの本から、このコードスニペットを通じて働いている

は:StructureMapを使用して静的クラスにセッターインジェクションを指定する方法は?

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

私は私のサービス層(この例では、私はOrderSumittedEventを上げています)、DomainEventsからDomainEvents.Raiseにアクセスするために行くnullある(ときそれが必要)のStructureMap経由で設定すること:

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

私は明示的にこのようなStructureMapDomainEventHandlerFactoryに手でDomainEvents.DomainEventHandlerFactoryを設定しない限り:

以下
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 }); 
    } 
} 

.WhatDoIHave()を使用してStrucutureMapの出力であり、そしてのStructureMapはタイプIDomainEventHandlerFactoryためStructureMapDomainEventHandlerFactoryの構成されたインスタンスを持っていることが表示されます。ここではダンプです:

================================================================================================================================================================================================================================================================================================================================================================================================ 
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を使用しましたが、私はセッターインジェクションを使用していない、また私は(それも理にかなっている場合)、静的なクラスでのStructureMapを使用して対処しなければならなかったが、私は」なぜこのコードがうまくいかないのかが少し失われています。

Setter Injectionをこのようなクラスの静的実装で使用することはできますか? StructureMapを正しく使用していませんか? DomainEventsクラスをSingletonとして作成するのは、StructureMapでなければなりません。静的実装を取り除くことはできますか?

おかげで、 マイク

+2

これに対する評決は何ですか? – sawe

答えて

0

それは、このようなクラスの静的な実装とセッター・インジェクションを使用することは可能ですか?

いいえ作成可能なクラスでのみ可能です。

私は適切にStructureMapを使用していませんか?

あなたはそうではありません。依存性注入はを処理し、インスタンスを作成して提供します。定義上、静的クラスはコードでは作成できないため、非注入可能です。

DomainEventsクラスをシングルトンとして作成する必要がありますか?そして、私は静的実装を取り除くことができますか?

このデザインの中心的な特徴は、イベントが1回だけ発生するように、単一のインスタンスを使用することです。私はどのデザインパターンを使用しているのかよく分かりませんが、多くの場合Action<T>またはFunc<T>をイベントに置き換えることができます。シングルトンのライフスタイルを適切に使用すると、おそらくすべてのクラス間で共有できる単一のインスタンスを登録できます静的なクラスに頼るよりも。

静的イベントが絶対に必要な場合、IDomainEventHandlerFactoryのインスタンスをアプリケーション起動コードに挿入することができます。インスタンスを解決し、登録コードを完了した後で手動で設定します(composition root)。アプリケーションは、あなたの静的クラスにいくつかのガード条項を置くことができ、それが設定される前に、複数回またはそれを使用して、それを呼び出すことにより、セッターを乱用しないようにするには

// 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."); 
     } 
    } 
} 
関連する問題