私はこのwcfメソッドを持っています
Profile GetProfileInfo(string profileType, string profileName)
およびビジネスルール:
profileTypeが「A」の場合、データベースから読み取られます。
profileTypeが"B"の場合、xmlファイルから読み取ります。
問題は、依存性注入コンテナを使用してそれを実装する方法ですか?
私はこのwcfメソッドを持っています
Profile GetProfileInfo(string profileType, string profileName)
およびビジネスルール:
profileTypeが「A」の場合、データベースから読み取られます。
profileTypeが"B"の場合、xmlファイルから読み取ります。
問題は、依存性注入コンテナを使用してそれを実装する方法ですか?
まず、次のようなIProfileRepositoryがあると仮定します。
public interface IProfileRepository
{
Profile GetProfile(string profileName);
}
2つの実装と同様に:DatabaseProfileRepository
とXmlProfileRepository
。問題は、profileTypeの値に基づいて正しいものを選択したいということです。
この抽象ファクトリを導入することでこれを行うことができます:
public interface IProfileRepositoryFactory
{
IProfileRepository Create(string profileType);
}
IProfileRepositoryFactoryがサービス実装に注入されていると仮定すると、次のようにGetProfileInfoメソッドを実装できます。
public Profile GetProfileInfo(string profileType, string profileName)
{
return this.factory.Create(profileType).GetProfile(profileName);
}
IProfileRepositoryFactoryの具体的な実装は、次のようになります。
public class ProfileRepositoryFactory : IProfileRepositoryFactory
{
private readonly IProfileRepository aRepository;
private readonly IProfileRepository bRepository;
public ProfileRepositoryFactory(IProfileRepository aRepository,
IProfileRepository bRepository)
{
if(aRepository == null)
{
throw new ArgumentNullException("aRepository");
}
if(bRepository == null)
{
throw new ArgumentNullException("bRepository");
}
this.aRepository = aRepository;
this.bRepository = bRepository;
}
public IProfileRepository Create(string profileType)
{
if(profileType == "A")
{
return this.aRepository;
}
if(profileType == "B")
{
return this.bRepository;
}
// and so on...
}
}
今、あなたはあなたのためにそれをすべて配線するためにあなたの選択したDIコンテナを手に入れる必要があります...
マークによる素晴らしい答えですが、与えられた解決策は抽象ファクトリではなく、標準ファクトリパターンの実装です。Marksクラスが標準ファクトリパターンUML図にどのように適合するかを確認してください。ファクトリパターンUMLに適用される上記のクラスを表示するには、ここをクリックしてください
ファクトリパターンでは、ファクトリは具象クラスを認識しているので、ProfileRepositoryFactory
以下のようにコードをはるかに単純にすることができます。異なるリポジトリをファクトリに注入する際の問題は、新しい具象タイプを追加するたびに、より多くのコード変更があることです。以下のコードを使用すると、スイッチを更新して新しい具象クラスを含めるだけで済みます
public class ProfileRepositoryFactory : IProfileRepositoryFactory
{
public IProfileRepository Create(string profileType)
{
switch(profileType)
{
case "A":
return new DatabaseProfileRepository();
case "B":
return new XmlProfileRepository();
}
}
}
抽象ファクトリは、具体的なクラスを指定せずに、関連オブジェクトまたは依存オブジェクトのファミリを作成するために使用される、より高度なパターンです。ここで利用可能なUMLクラス図はそれをよく説明しています。