vig*_*ity 11 .net dependency-injection ninject inversion-of-control
我有一个看起来大致如下的依赖链:
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 { ... }
Run Code Online (Sandbox Code Playgroud)
到目前为止,我一直在使用基于约定的绑定,但这已经不够好了,因为我有多个实现IFtpSettings.所以我决定使用一些上下文绑定.乍一看,kernel.Bind<>().To<>().WhenInjectedInto<>()看起来很有希望,但这只对第一级有帮助,这意味着如果我有一个CarSalesFtpFileProvider和一个MotorcycleSalesFtpProvider我可以做到这一点:
kernel.Bind<IFtpSettings>().To<CarSalesFtpSettings>()
.WhenInjectedInto<CarSalesFtpFileProvider>();
kernel.Bind<IFtpSettings>().To<MotorcycleSalesFtpSettings>()
.WhenInjectedInto<MotorcycleSalesFtpFileProvider>();
Run Code Online (Sandbox Code Playgroud)
但是创建两个具体实现似乎非常愚蠢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);
}
Run Code Online (Sandbox Code Playgroud)
因此,如果构造函数请求IFtpSettings,我们会递归请求树以查看链中所请求的任何服务/类型是否与提供的类型(CarSalesBatchJob或MotorcycleSalesBatchJob)匹配,如果是,则返回true.如果我们一直到达链的顶部,我们返回false.
很抱歉有很长的背景说明.
这是我的问题:我有什么理由不这样解决问题吗?这被认为是不好的形式吗?有没有更好的方法来查找祖先请求类型?我应该将我的课程/依赖链重构为更"愉快"的方式吗?
您应该使用request.Target.Member.ReflectedType而不是request.Service这是实现类型.
此外,当AnyAncestorNamed不需要属性时.您可以使用该Named方法标记作业的绑定.
| 归档时间: |
|
| 查看次数: |
2154 次 |
| 最近记录: |