我的nDepperlect Reports警告说,"非静态类应进行实例化或变为静态"。返回列表中的大多数类都是通过我的IOC容器(Unity)注册的,并在运行时由IOC框架实例化。
鉴于Ndepended正在执行静态分析,因此不会意识到运行时的实例化。我希望可以调整CQL以使其了解我的容器。
这是Ndectectecon的样板查询:
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容器注册中引用的类?
的确,您可以在Ndepperion -epident -epident用户声音网站上投票支持IOC框架的NDEPD支持。这是将来将在未来实施的功能。
目前,您可以使用一个属性处理。在您的代码中创建一个属性类,例如名为MyProduct.IoCInstantiatedAttribute
。
然后,您可以使用此属性仅由IOC实例化的所有类。由于仅在调试构建中需要此属性(由Ndependepent分析),我会使用条件调试语法建议。
#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 实例化)。