Post build .Net assembly checking (attributes and call graph)
All 开发者_Python百科methods in an assembly are marked with a one of two attributes: [Bottleneck] or [Caching]. [Caching] methods do some caching and they should be implemented in the clearest way, since they are called rarely. On contrary, [Bottleneck] methods are called every time the assembly is being used by a server (often enough), so they should be optimized.
Is there a way to check: 1. Every method is marked with one of the attributes. 2. No [Bottleneck] method calls [Caching] method.
I'd like to have this tool integrated with VS 2010.
Regards,
You could always write your own custom tool, using either reflection, Mono.Cecil or write your own FxCop / CodeAnalysis custom rule(s).
You could also use NDepend, which allows you to basically write "SQL like" queries upon your assemblies. Using this CQL (Code Query Language) you could check for your constraints. NDepend integrates into Visual Studio and also has a command line version for automated builds.
Especially with your 2nd requirement (call graph) I'm not sure if NDepend can do that. Your own tools could certainly, as could be done with a custom FxCop rule.
EDIT: Looking at NDepend's CQL specification, I'd be inclined to say that the 2nd requirement indeed is not (easily) doable.
To elaborate on the Christian answer, yes what you are asking for is doable with the new NDepend version thanks to the Code Query and Rule over LINQ capabilities. Disclaimer: I am one of the developers of the tool
Every method is marked with one of the attributes
Just write the CQLinq code rule:
warnif count > 0
from m in Application.Methods where
!m.IsConstructor && !m.IsPropertyGetter && !m.IsPropertySetter &&
!m.HasAttribute("MyNamespace.Caching") &&
!m.HasAttribute("MyNamespace.Bottleneck")
select m
No [Bottleneck] method calls [Caching] method.
Just write the slightly more complex code rule:
warnif count > 0
let bottleneckMethods =
from m in Application.Methods where
!m.IsConstructor && !m.IsPropertyGetter && !m.IsPropertySetter &&
!m.HasAttribute("MyNamespace.Bottleneck")
select m
let cachingMethods =
(from m in Application.Methods where
!m.IsConstructor && !m.IsPropertyGetter && !m.IsPropertySetter &&
!m.HasAttribute("MyNamespace.Caching")
select m).ToHashSet() // <- ToHashSet() Just for optimization with Intersect()
from m in bottleneckMethods
let cachingMethodsCalled = m.MethodsCalled.Intersect(cachingMethods)
where cachingMethodsCalled.Count() > 0
select new { m, cachingMethodsCalled }
精彩评论