我有一个大致如下所示的依赖链:
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
和 aMotorcycleSalesFtpProvider
我可以这样做:
kernel.Bind<IFtpSettings>().To<CarSalesFtpSettings>()
.WhenInjectedInto<CarSalesFtpFileProvider>();
kernel.Bind<IFtpSettings>().To<MotorcycleSalesFtpSettings>()
.WhenInjectedInto<MotorcycleSalesFtpFileProvider>();
但是创建两个具体的实现似乎很愚蠢FtpFileProvider
,实际上只是在我希望它们使用的设置上有所不同。我看到有一个方法叫做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。
抱歉,背景解释太长了。
这是我的问题:我有什么理由不应该以这种方式解决问题?这被认为是不好的形式吗?有没有更好的方法来查找祖先请求类型?我应该将我的类/依赖链重组为更“令人愉快”的方式吗?