我的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容器注册中引用的类?
答案 0 :(得分:2)
实际上,您可以在NDepend User Voices site上投票支持IoC Framework的NDepend支持。这是将在未来实施的功能。
现在,您可以使用属性处理此问题。在代码中创建一个属性类,例如名为MyProduct.IoCInstantiatedAttribute
。
然后,您可以使用此属性标记仅由IoC实例化的所有类。由于此属性仅在DEBUG构建时需要(由NDepend分析),我建议使用条件DEBUG语法。
#if DEBUG
[IoCInstantiated]
#endif
class MyClass { ... }
最后,您只需在相关规则中添加&& !t.HasAttribute("MyProduct.IoCInstantiatedAttribute")
etvoilà!
此外,您还可以编写规则以确保具有此属性的类不会在某处实例化。这样你就可以保持这个属性的使用清洁!
// <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实例化)。