2014-01-27 1 views
2

Мои отчеты NDepend предупреждают, что «нестатические классы должны быть созданы или статичны». Большинство классов в возвращаемом списке регистрируются через мой контейнер IOC (Unity) и создаются при помощи моей инфраструктуры IOC во время выполнения.Исключение классов, созданных через контейнер IOC из предупреждения NDepend

Учитывая, что 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 } 

Можно ли мне настроить этот запрос, чтобы исключить классы, на которые ссылаются в моей МОК контейнера регистрации?

ответ

2

Действительно, вы можете голосовать за поддержку NDepend для IoC Framework на NDepend User Voices site. Это функция, которая будет реализована в будущем.


В настоящее время вы можете справиться с этим с помощью атрибута. Создайте класс атрибута в своем коде, например, с именем 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) с первого взгляда.

+0

Спасибо, Патрик - это сработало хорошо. Я добавил атрибут в свой проект, обновил запросы соответственно и добавил также защитный запрос. Это помогло уменьшить шум в моих отчетах. Я среди тех, кто хотел бы, чтобы NDepend стал IOC-осведомленным. Предложение, указанное в предоставленной вами ссылке, тем не менее, специально указывает на синтаксический анализ XML для идентификации регистраций МОК. Хотя это потенциально полезно, большинство зарегистрированных в контейнерах регистрации происходят в коде, а не в конфигурации. Если NDepend сможет распознавать регистрацию контейнеров в коде, это было бы более полезно. – kiprainey

+1

Чтобы увеличить то, что сказал @Patrick, я также счел полезным исключить контроллеры MVC и Web API. Их можно исключить без добавления дополнительного атрибута: '! T.DeriveFrom (« System.Web.Http.ApiController ») && // Пропустить api-контроллеры, которые создаются через фреймворк '! T.DeriveFrom (" System.Web.Mvc.Controller ") && // Пропустить mvc-контроллеры, которые создаются через framework' – kiprainey