我们在NinjectModule
中为某些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
接口,扩展 IInspection
:
public interface IParseTreeInspection : IInspection
{
ParseTreeResults ParseTreeResults { get; set; }
}
这产生的问题是使用这些消耗拦截器的代码 - 注入的代理类型可以理解为似乎对IParseTreeInspection
一无所知,所以这个foreach
循环不会#39} ; t甚至迭代一次:
var enabledParseTreeInspections = _inspections.Where(inspection =>
inspection.Severity != CodeInspectionSeverity.DoNotShow
&& inspection is IParseTreeInspection);
foreach (var parseTreeInspection in enabledParseTreeInspections)
{
(parseTreeInspection as IParseTreeInspection).ParseTreeResults = parseTreeWalkResults;
}
有什么方法我可以多绑定IInspection
(即构造函数注入IEnumerable<IInspection>
)和仍然可以告诉IParseTreeInspection
实例当Ninject是注射拦截器?
答案 0 :(得分:0)
Here is one way to do it:
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>>();
}
}
This code checks if the type is assignable from IParseTreeInspection
, i.e., it implements IParseTreeInspection
, and if so, it creates a named binding from IParseTreeInspection
to this type and configures the interception here. This will make sure that the proxy objects (created by the interceptor) will implement IParseTreeInspection
. Then it creates another binding from IInspection
to a delegate invocation that would use the kernel to resolve IParseTreeInspection
via the the first binding (using the binding name).