私はリポジトリからDTOを取得するサービス層を持っています。そのDTOのプロパティによっては、DTOで計算を実行するために2つの戦略のうちの1つを使用する必要があります。適切な戦略を返すためのファクトリを作成しました。オブジェクトをインスタンス化するためにDIコンテナ(Munq)を使用しています。これはDependency Injectionの正しい使用ですか?
public class CalculationFactory
{
private readonly IDependencyResolver _resolver;
public CalculationFactory(IDependencyResolver resolver)
{
ThrowIfNullArgument(resolver, "resolver", typeof(IDependencyResolver));
_resolver = resolver;
}
public static ICalculation CreateCalculator(int serviceType)
{
switch (serviceType)
{
case 1: return _resolver.Resolve<ICalculation>("Type1");
case 2: return _resolver.Resolve<ICalculation>("Type2");
default: return _resolver.Resolve<ICalculation>("InvalidType");
}
}
}
使用するために適切な計算をインスタンス化/解決するために使用することができるように、私は工場をインスタンス化するとき、依存リゾルバに渡すために私を必要とします。これは正しいアプローチですか?新しいタイプの計算を追加したい場合は、工場のCreateCalculatorメソッドを更新して新しいタイプを登録する必要があります。
更新(ロング) 私は恐れている提案を実際に牽引していません。私は.NetのMark's DIのコピー、特にリファクタリングの第6章に戻ってきました。だから私はクラスMeterReadingsと私はランタイム値に基づいて2つの計算のいずれかを使用して電荷を計算する必要があります。私は抽象的な工場をミックスに追加しますが、私のコンクリート工場ではまだ新しいが必要です。私はここでのポイントを欠けているように感じる:
public enum ServiceType
{
Actuals = 1, CopyBlock,
}
public interface IChargeCalculator
{
decimal CalculateCharge();
}
public interface IChargeCalculatorFactory
{
IChargeCalculator CreateChargeCalculator(ServiceType serviceType);
}
public class MeterReading
{
private readonly IChargeCalculatorFactory chargeCalculatorFactory;
public MeterReading(IChargeCalculatorFactory chargeCalculatorFactory)
{
if (chargeCalculatorFactory == null)
throw new ArgumentNullException("chargeCalculatorFactory");
this.chargeCalculatorFactory = chargeCalculatorFactory;
}
}
public class ConcreteChargeCalculatorFactory : IChargeCalculatorFactory
{
public IChargeCalculator CreateChargeCalculator(ServiceType serviceType)
{
switch (serviceType)
{
case ServiceType.Actuals : return new ActualsChargeCalculator();
default: return new CopyBlockChargeCalculator();
}
}
}
しかし、私の容器に私は別の電卓を登録することができ、私は具体的な工場としてコンテナに渡した場合、私のような何かを得る(テストしていません)、次のどの率直に言って、私にとってかなり合理的だ。どんなフィードバック/明確化も歓迎されるでしょう。
Container.Register<IChargeCalculator>("Actuals",
c => new ActualsChargeCalculator());
Container.Register<IChargeCalculator>("CopyBlock",
c => new CopyBlockChargeCalculator());
...
public enum ServiceType
{
Actuals = 1, CopyBlock,
}
public interface IChargeCalculator
{
decimal CalculateCharge();
}
public class MeterReading
{
private readonly IDependencyResolver chargeCalculatorFactory;
private ServiceType serviceType;
public MeterReading(IDependencyResolver chargeCalculatorFactory)
{
if (chargeCalculatorFactory == null)
throw new ArgumentNullException("chargeCalculatorFactory");
this.chargeCalculatorFactory = chargeCalculatorFactory;
}
public decimal Charge
{
get
{
return chargeCalculatorFactory.Resolve<IChargeCalculator>(serviceType.ToString());
}
}
}
ここで依存関係を解決する方法は、通常、「サービスロケータ」パターン(または、あなたの視点に応じてアンチパターン)と呼ばれます。http: /blog.ploeh.dk/2010/02/03/ServiceLocatorIsAnAntiPattern.aspx私は通常、Service Locatorパターンを避けようとしますが、やむを得ないこともあります。 – CodingWithSpike
rally25rsに感謝します。私はMarkの投稿を見ましたが、Service Locatorからより良いものにリファクタリングする方法はありません。 –
ここにある方法:http://stackoverflow.com/questions/1943576/is-there-a-pattern-for-initializing-objects-created-via-a-di-container/1945023#1945023 –