2011-06-22 21 views
1

WCFデータサービス(OData)でUnityを使用しようとしています。UnityとOData(WCFデータサービス)

public class PatientService : DataService<IPatientRepository> 

私は団結が実行時にIPatientRepositoryのための正しいオブジェクトを挿入したい(実PatientRepositoryまたは私がテストに使用偽造1のいずれか。)

私が持っている:私はこのようなコードを持っています

IUnityContainer container = new UnityContainer(); 
container.RegisterType<IPatientRepository, MyEntities>(); 

しかし、私は実行したときに私が取得:行わ

サーバーは、エラー処理が発生しましたリクエスト。例外メッセージは 'データプロバイダを作成できません。 'PatientService.PatientService'のデータソースの 'RepositoryInterfaces.IPatientRepository'は抽象型です。 '

この依存性を注入する方法はありますか?それとも本当のクラスをその場所に置く必要がありますか?

答えて

0

WCF Data Servicesはコンテナについて認識していないため、渡すインターフェイスの実装を調べるために呼び出すことはできません。

同様に、コンテナはコンストラクタインジェクションを実行できますが、DataServiceでTを動的に指定することはできません<T>。

私が知る限り、DataServiceをInterfaceで使用して実装をインジェクトする方法はありません。

EDIT:何が動作するはずビテックがコメントで指摘したように、単にインターフェースを使用して、クラスのDataSource <T>を宣言してからCreateDataSource()メソッドをオーバーライドすることです。その方法では、あなたがしてIYourInterfaceの実装にのServiceLocator呼び出しを行うことができます。もちろん、この

var myService = ServiceLocator.Get<IYourInterface>(); 

を使用すると、サービスの場所のためのあなたのコンテナを設定する必要があります。

パターン& Practicesグループは、サービスロケータパターン用のUnityアダプタを実装しています(http://commonservicelocator.codeplex.com/wikipage?title=Unity%20Adapter&referringTitle=Home&ProjectName=commonservicelocatorを参照)。

サービスロケータのパターンについては、http://msdn.microsoft.com/en-us/library/ff648968.aspxを参照してください。

+0

DataService を定義できます.Tはインターフェイスです。ただし、CreateDataSourceメソッドをオーバーライドして、そのインターフェイスを実装するコンテキストクラスをインスタンス化する必要があります。それが注射でうまくいくかどうかわからない。 –

+0

@Vitek:CreateDataSourceをオーバーライドして、オーバーライドでServiceLocatorを使用しているとしたら?それはうまくいくかもしれない。 –

+0

ServiceLocatorを使用しないようにしてください。これは、Microsoft Patterns and PracticesのServiceLocatorクラスのオリジナル開発者であったMark Seemannのhttp://blog.ploeh.dk/2010/02/03/ServiceLocatorisanAnti-Pattern/に記載されているような反パターンです。彼は正当な理由でそれをすぐに消してしまった。 –

1

ServiceLocatorクラスとServiceLocator (anti)patternは、ここでは使用しないでください。下のコードはサービスロケータ(アンチ)パターンのようですが、それほどではありません。

CreateDataSourceメソッドは、オブジェクトグラフを構成するために見つかったリクエストライフサイクルの最も早い時点です。ここでは、Composition Rootとして使用されます。ブートストラップは、XMLまたはコードからロードするかどうかにかかわらず、Unity構成を呼び出すヘルパークラスです。

public class PatientService : DataService<IPatientRepository> 
{ 
    public static void InitializeService(DataServiceConfiguration config) 
    { 
     // TODO: set rules to indicate which entity sets and service 
      operations are visible, updatable, etc. 
      ... 
    } 

    [WebGet] 
    public IQueryable<Patient> Patients() 
    { 
     return from p in CurrentDataSource.Patients select p; 
    } 

    protected override IPatientRepository CreateDataSource() 
    { 
     IUnityContainer container = new UnityContainer(); 
     Bootstrapper.Initialise(container); 
     return container.Resolve<IPatientRepository>(); 
    } 
} 

ので@RoyはCreateDataSource()メソッドにあなたを指すように正しかったです。しかし、ServiceLocatorの使用は、クラスとして、またはパターンとして避けるべきです。残念ながら、マイクロソフトではServiceLocatorやDependencyResolverなどのクラスを使用してみんなにServiceLocatorルートを強制的に強制していました。

+0

'DataService 'ジェネリック型 'T'は、' CreateDataSource() 'メソッドを扱うためのインタフェースでもありません。 –

関連する問題