After my previous post regarding NDepend I have decided to give it another go, this time on a new project.
I am using Visual Studio 2015 for the first time so need to install NDepend for VS2015; this is now very easy after setting things up last time. Navigate to the NDepend folder, run NDepend.VisualStudioExtension.Installer.exe
and click install for VS 2015.
I’ve just started a new project, Qujck.MarkdownEditor. At the current point of time the code reads some markdown and renders it for display in a WebBrowser
control, using google prettify to add syntax highlighting to code snippets.
Analysing the project this early on was a pleasant experience with only 93 violations.
- Avoid namespaces mutually dependent
This took me a moment to figure out. What I have is classes in the namespacesQujck.MarkdownEditor.Queries
andQujck.MarkdownEditor.Aspects
that both make use of a couple of extension methods inQujck.MarkdownEditor
. This is the sort of thing that leads to a namespace such asCommon
,Core
,Infrastructure
etc and on this occasion I will go withInfrastructure
.
Great, 91 violations to go …
- Avoid empty interfaces * 2
These 2 warnings are not errors for me, the 2 interfaces areIQuery<TResult>
andICommand
that I have highlighted in numerous other posts. The recommendation for ignoring these is to create a dedicated attribute and modify the rules with something along the lines of&& !m.HasAttributes("Namespace.IsNotDeadAttribute")
. This is a solution but it’s not for me, my code does not need to know (and arguably should not know) about the analysis tool. My preference is to hard code these 2 interfaces into the rules and can be achieved by tweaking the query:
warnif count > 0 from t in JustMyCode.Types where
t.IsInterface &&
t.NbMethods == 0 &&
!new string[]
{
"IQuery<TResult>",
"ICommand"
}.Contains(t.Name)
select new { t, t.TypesThatImplementMe }
- Class with no descendant should be sealed if possible * 2
One is theMainForm
generated by Visual Studio and the other is theCompositionRoot
class that I have recently added for doing Pure DI. Both of these can besealed
- Instance size shouldn’t be too big
This theMainForm
so I can ignore this. In fact I will ignore allForm
s:
warnif count > 0 from t in JustMyCode.Types where
t.SizeOfInst > 64 &&
t.BaseClass.Name != "Form"
orderby t.SizeOfInst descending
select new { t, t.SizeOfInst, t.InstanceFields }
- Nested types should not be visible
Referring to this post, I like to organise my Command and Query handlers by housing them within a static parent class, another query tweak will fix this:
warnif count > 0 from t in JustMyCode.Types where
t.IsNested &&
!t.IsGeneratedByCompiler &&
!t.IsPrivate &&
!new string[]
{
"Query",
"Query+Handlers",
"Command",
"Command+Handlers"
}.Contains(t.ParentType.Name)
select new {
t,
t.Visibility
}
- Avoid namespaces with few types
Qujck.MarkdownEditor.Properties
is VS generated
Qujck.MarkdownEditor.Infrastructure
was created to fix avoid namespaces mutually dependent above
Qujck.MarkdownEditor
is the root namespace
I’m going to ignore this one for now and see how the solution evolves. - Types with disposable instance fields must be disposable
This isMainForm
again. Bizarrely the generated codeMainForm.Designer.cs
does have aDispose
method, the fix is to simple addIDisposable
as inpublic sealed partial class MainForm : Form, IDisposable
- Avoid public methods not publicly visible
Referring to this post I would normally have Command and Query handlers nested within aninternal static partial class Handlers
but have madeHandlers
public for now to remedy this error - Types that could have a lower visibility
Now this is the case while I am doing Pure DI, but if I shift over to using SimpleInjector then the classes would all need to have publicly accessibly constructors. I am going to disable this rule. - Methods that could have a lower visibility
As above, I will disable this rule. - Fields should be marked as ReadOnly when possible
2 out of 3 fixed, the other is thecomponents
field of the generated codeMainForm.Designer.cs
. I’m going to ignore this one. - Methods names should begin with an Upper character
Fixed. - Static fields should be prefixed with a ‘s_’
Deleted! - Instance fields should be prefixed with an ‘m_’
This rule is not for me: I am going to disable this rule. - Avoid defining multiple types in a source file
Fixed. - Mark assemblies with CLSCompliant
Fixed.