【问题标题】:Excluding classes instantiated via IOC container from NDepend warning从 NDepend 警告中排除通过 IOC 容器实例化的类
【发布时间】:2014-01-27 18:50:06
【问题描述】:

我的 NDepend 报告警告说“非静态类应实例化或转为静态类。”返回列表中的大多数类都是通过我的 IOC 容器 (Unity) 注册的,并在运行时由我的 IOC 框架实例化。

鉴于 NDepend 正在执行静态分析,它不会意识到运行时实例化。我希望可以调整 CQL 以使其了解我的容器。

这是 NDepend 执行的样板查询:

warnif count > 0
from t in JustMyCode.Types
where  t.IsClass &&
//!t.IsPublic &&   // if you are developping a framework, 
                   // you might not want to match public classes
  !t.IsStatic && 
  !t.IsAttributeClass && // Attributes class are never seen as instantiated
  !t.DeriveFrom("System.MarshalByRefObject".AllowNoMatch()) // Types instantiated through remoting infrstructure

// find the first constructor of t called
let ctorCalled = t.Constructors.FirstOrDefault(ctor => ctor.NbMethodsCallingMe > 0)

// match t if none of its constructors is called.
where ctorCalled == null
select new { t, t.Visibility }

我是否可以调整此查询以排除在我的 IOC 容器注册中引用的类?

【问题讨论】:

    标签: ndepend


    【解决方案1】:

    确实,您可以在NDepend User Voices site 上投票支持 IoC 框架的 NDepend 支持。这是将来会实施的功能。


    现在,您可以使用属性来处理这个问题。在您的代码中创建一个属性类,例如名为MyProduct.IoCInstantiatedAttribute。

    然后,您可以使用此属性标记由 IoC 单独实例化的所有类。由于仅在 DEBUG 构建(由 NDepend 分析的那个)上需要此属性,我建议使用条件 DEBUG 语法。

    #if DEBUG
    [IoCInstantiated]
    #endif
    class MyClass { ... }
    

    最后,您只需在相关规则中添加&& !t.HasAttribute("MyProduct.IoCInstantiatedAttribute")等等!

    此外,您还可以编写规则以确保具有此属性的类不会在某处实例化。这样你就可以保持这个属性的使用干净!

    // <Name>Types tagged with attribute IoCInstantiated must not be instantiated elsewhere</Name>
    warnif count > 0 
    from t in Types 
    where t.HasAttribute ("MyProduct.IoCInstantiatedAttribute") 
    let methodsInstiatingMe = Application.Methods.ThatCreateA(t)
    where methodsInstiatingMe.Any()
    select new { t, methodsInstiatingMe }
    

    我个人发现使用这样的属性很棒,因为它还记录了代码。当开发人员查看此类课程时,他可以一目了然地了解这条重要信息(仅通过 IoC 实例化)。

    【讨论】:

    • 谢谢你,帕特里克——效果很好。我将属性添加到我的项目中,相应地更新了查询,并添加了保护查询。它有助于减少我的报告中的噪音。我是那些希望看到 NDepend 成为 IOC 意识的人之一。但是,您提供的链接中引用的提案特别提到了 XML 解析以识别 IOC 注册。虽然这可能很有用,但我遇到的大多数容器注册都发生在代码中,而不是配置中。如果 NDepend 可以识别代码中的容器注册,那就更有用了。
    • 为了补充@Patrick 所说的内容,我还发现排除 MVC 和 Web API 控制器很有用。这些可以在不添加附加属性的情况下排除:!t.DeriveFrom("System.Web.Http.ApiController") &amp;&amp; // Skip api controllers, which are instantiated via the framework!t.DeriveFrom("System.Web.Mvc.Controller") &amp;&amp; // Skip mvc controllers, which are instantiated via the framework
    猜你喜欢
    • 1970-01-01
    • 2018-05-24
    • 2012-08-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-18
    相关资源
    最近更新 更多