c# - 如何访问拦截器上的扩展接口(interface)?

标签 c# dependency-injection ninject ninject-interception

我们在 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/

相关文章:

c# - 托管后日期时间出错

c# - Elasticsearch.net NEST Bool查询未生成预期的请求

c# - 在不创建新实例的情况下反射(reflect)嵌套实例

Haskell - 如何将具有不同依赖项子集的组件连接在一起?

c# - 在 MemoryCache 调用上停止重入

c# - 带参数的 IoC 记录器

.net-core - 未注册服务类型

ninject - Ninject 2 中的上下文变量

.net - 获取单例实例

c# - 使用 Ninject 自定义 OptionalAttribute