views:

74

answers:

2

Some background: We require all of our DTO objects to be serializable so that they can be stored in session or cached.

As you can imagine, this is extremely annoying and prone to error... is there any automated way (ideally as part of the build process) using Visual Studio 2010 to ensure that all classes in a namespace are marked with the [Serializable] attribute?

+4  A: 

You can't find all possible classes in a namespace - but you can find all classes within a given assembly which have the specified namespace, and check those.

string dtoNamespace = ...;
Assembly assembly = ...;
var badClasses = assembly.GetTypes()
                         .Where(t => t.Namespace == dtoNamespace)
                         .Where(t => t.IsPublic) // You might want this
                         .Where(t => !t.IsDefined(typeof(SerializableAttribute),
                                     false);

Assert that badClasses is empty in whatever way you want :)

EDIT: As mentioned in the comments, the IsSerializable property is kinda handy here :)

Jon Skeet
Nice (free) solution - but I'd like easy integration into the build process. If I could have accepted two answers I would!
DanP
@DanP: Is there much disadvantage in just putting this as one of your unit tests? That's what I'd do. So long as you run unit tests regularly it should be fine.
Jon Skeet
@Jon - good point. One would hope the red test would be enough to fail the build!
Rob Levine
@Jon - Good idea - I suppose that's an option as well.
DanP
@Jon - Just an additional note on this; I found that changing the serialization check to .Where(t => !t.IsSerializable) read a little nicer, thanks for the suggestions here!
DanP
@DanP: Doh - didn't know about that property :)
Jon Skeet
+5  A: 

One tool you might like to think about, that is easily integrated into your build, is NDepend. This lets you run various code metrics, which you can then use to warn/fail your build.

In CQL (the built in query language in NDepend), you would write something like:

WARN IF Count > 0 IN SELECT TYPES FROM NAMESPACES "namespace" WHERE !IsSerializable  

Obviously this will only find namespaces for types that are included in assemblies within your solution, but I assume that's what you mean.

NDepend can be run automatically as part of your build within VS, or on a seperate build server. It can also be run as a standalone application.

Rob Levine
Very slick...I've casually had a look at NDepend before, but I guess I'm all out of excuses not to use it now.
DanP