我们在 NinjectModule
中定义了一个多重绑定(bind)对于一些 IInspection
界面,像这样:
private void BindCodeInspectionTypes()
{
var inspections = Assembly.GetExecutingAssembly()
.GetTypes()
.Where(type => type.BaseType == typeof (InspectionBase));
// multibinding for IEnumerable<IInspection> dependency
foreach (var inspection in inspections)
{
var binding = Bind<IInspection>().To(inspection).InSingletonScope();
binding.Intercept().With<TimedCallLoggerInterceptor>();
binding.Intercept().With<EnumerableCounterInterceptor<InspectionResultBase>>();
}
}
因此拦截器代理类型将为 IInspection
.然而一些inspection
类型实现 IParseTreeInspection
接口(interface),扩展 IInspection
:
public interface IParseTreeInspection : IInspection
{
ParseTreeResults ParseTreeResults { get; set; }
}
这产生的问题是这段使用拦截器的代码——可以理解的是,注入(inject)的代理类型似乎对 IParseTreeInspection
一无所知。 , 所以这个 foreach
循环甚至不迭代一次:
var enabledParseTreeInspections = _inspections.Where(inspection =>
inspection.Severity != CodeInspectionSeverity.DoNotShow
&& inspection is IParseTreeInspection);
foreach (var parseTreeInspection in enabledParseTreeInspections)
{
(parseTreeInspection as IParseTreeInspection).ParseTreeResults = parseTreeWalkResults;
}
有什么方法可以多重绑定(bind) IInspection
(即构造函数注入(inject) IEnumerable<IInspection>
)并且仍然能够告诉 IParseTreeInspection
Ninject 注入(inject)拦截器的实例?
最佳答案
这是一种方法:
foreach (var inspection in inspections)
{
if (typeof (IParseTreeInspection).IsAssignableFrom(inspection))
{
var binding = Bind<IParseTreeInspection>()
.To(inspection)
.InSingletonScope()
.Named(inspection.FullName);
binding.Intercept().With<TimedCallLoggerInterceptor>();
binding.Intercept().With<EnumerableCounterInterceptor<InspectionResultBase>>();
Bind<IInspection>().ToMethod(
c => c.Kernel.Get<IParseTreeInspection>(inspection.FullName));
}
else
{
var binding = Bind<IInspection>().To(inspection).InSingletonScope();
binding.Intercept().With<TimedCallLoggerInterceptor>();
binding.Intercept().With<EnumerableCounterInterceptor<InspectionResultBase>>();
}
}
此代码检查类型是否可从 IParseTreeInspection
分配,即它实现了 IParseTreeInspection
,如果是,它会从 IParseTreeInspection
创建一个命名绑定(bind)为这种类型并在此处配置拦截。这将确保代理对象(由拦截器创建)将实现 IParseTreeInspection
.然后它从 IInspection
创建另一个绑定(bind)到将使用内核解析 IParseTreeInspection
的委托(delegate)调用通过第一个绑定(bind)(使用绑定(bind)名称)。
关于c# - 如何访问拦截器上的扩展接口(interface)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38313097/