おおよそ次のような依存関係チェーンがあります。
public class CarSalesBatchJob
{
public CarSalesBatchJob(IFileProvider fileProvider)
{ ... }
}
public class MotorcycleSalesBatchJob
{
public MotorcycleSalesBatchJob(IFileProvider fileProvider)
{ ... }
}
public class FtpFileProvider : IFileProvider
{
public FtpFileProvider(IFtpSettings settings)
{ ... }
}
public class CarSalesFtpSettings : IFtpSettings { ... }
public class MotorcycleSalesFtpSettings : IFtpSettings { ... }
これまで、私は規約ベースのバインディングを使用してきましたが、IFtpSettings
. そこで、いくつかのコンテキスト バインディングを使用することにしました。最初は赤面kernel.Bind<>().To<>().WhenInjectedInto<>()
が有望に見えましたが、それは最初のレベルでのみ役立ちます。つまり、 aCarSalesFtpFileProvider
と aがあれば、MotorcycleSalesFtpProvider
これを行うことができます。
kernel.Bind<IFtpSettings>().To<CarSalesFtpSettings>()
.WhenInjectedInto<CarSalesFtpFileProvider>();
kernel.Bind<IFtpSettings>().To<MotorcycleSalesFtpSettings>()
.WhenInjectedInto<MotorcycleSalesFtpFileProvider>();
FtpFileProvider
しかし、私が使用したい設定だけが実際に異なる2つの具体的な実装を作成するのはかなりばかげているようです。というメソッドがあることがわかりましたWhenAnyAnchestorNamed(string name)
。しかし、このルートでは、属性と魔法の文字列をバッチ ジョブに配置する必要があり、それについてはあまり興味がありません。
また、バインディング ステートメントには昔ながらの.When(Func<IRequest, bool>)
メソッドがあることにも気付きました。そのため、バインディング ステートメントとしてこれを思いつきました。
//at this point I've already ran the conventions based bindings code so I need to unbind
kernel.Unbind<IFtpSettings>();
kernel.Bind<IFtpSettings>().To<CarSalesFtpSettings>()
.When(r => HasAncestorOfType<CarSalesBatchJob>(r));
kernel.Bind<IFtpSettings>().To<MotorcycleSalesFtpSettings>()
.When(r => HasAncestorOfType<MotorcycleSalesBatchJob>(r));
// later on in the same class
private static bool HasAncestorOfType<T>(IRequest request)
{
if (request == null)
return false;
if (request.Service == typeof(T))
return true;
return HasAncestorOfType<T>(request.ParentRequest);
}
したがって、コンストラクターが IFtpSettings を要求した場合、要求ツリーを再帰的に調べて、チェーン内の要求されたサービス/タイプのいずれかが提供されたタイプ (CarSalesBatchJob または MotorcycleSalesBatchJob) と一致するかどうかを確認し、一致する場合は true を返します。チェーンの一番上まで到達すると、false が返されます。
背景説明が長くなってすみません。
これが私の質問です。この方法で問題にアプローチしてはいけない理由はありますか? これは悪いフォームと見なされますか? 祖先のリクエスト タイプを見つけるより良い方法はありますか? クラス/依存関係チェーンをより「快適な」方法に再構築する必要がありますか?