我有一个大致如下所示的依赖链:
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<>()
看起来很有希望,但这只在第一级有帮助,这意味着如果我有一个CarSalesFtpFileProvider
and a MotorcycleSalesFtpProvider
我可以这样做:
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。
抱歉,背景解释很长。
这是我的问题:我有什么理由不应该以这种方式解决问题吗?这被认为是不好的形式吗?有没有更好的方法来查找祖先请求类型?我应该将我的类/依赖链重组为更“令人愉快”的方式吗?