I want to build a visual studio plugin that automatically annotates classes for serialization. For example for the built in binary serializer I could just add [Serializable] to the class declaration, for WCF it could add [DataContract] to the class and [DataMember] to the members and properties (I could get [KnownType] information through reflection and annotate where appropriate). If using protocol buffers it could add [ProtoContract], [ProtoMember] and [ProtoInclude] attributes and so on.
I am assuming that the classes we are going to use this on are safe to serialize (so no sockets or nonserializable stuff in there). What I want to know is what is the easier way to take an existent piece of code (or a binary if that's easier) and add those attributes while preserving the rest of the code intact. I am fine with the output being source code or binary.
It comes to mind the idea of a using a C# parser, parse everything find the interesting code elements, annotate them and write back the code. However that seems to be very complex given the relatively small amount of modifications I want to make to the code. Is there an easier way to do so?
Visual Studio already has an API for discovering and emitting code which you might take a look at. It's not exactly a joy to use but could work for this purpose.
While such a plugin would certainly be a useful thing, I would consider rather making an add-in for a tool like ReSharper instead of VS directly. The advantage is somebody already solved the huge pile of problems you haven't even dreamed of yet and so it will be a lot easier to build such a specific functionality.
it looks to me like you need to have a MSBuild task similar to this one http://kindofmagic.codeplex.com/. is that about right?
Related
Trying to get my mind around google protobuf. I found some implementation of protobuf in C# but they seems to lack one feature: the ability to generate .proto files automatically from an existing C# class decorated with attributes.
The reason I want to do it this way instead of going from auto-generated C# classes from .proto file is because I already have the C# classes defined in my project and I don't want to duplicate them just to satisfy ProtoBuf.
Does anyone have encountered such a scenario?
Update
Is this possible to just decorate a C# class and not use a .proto file to use protobuf?
Good news; what you have described (having existing C# classes) is the expected use-case of protobuf-net. All the .proto stuff ("protogen", the VS add-in, etc) were all added as afterthoughts. The core of protobuf-net doesn't know about them or care about them.
protocol buffers defines a DSL (.proto, as you mention) that is shared between implementations, and is (sometimes) used for code generation. When I first wrote protobuf-net, the code-generation aspect wasn't my biggest concern - simply that .NET developers are generally guilty (myself included) of "implementation first" rather than "contract first".
As a consequence, protobuf-net doesn't need .proto files to work; an attributed class is sufficient to unambiguously serialize/deserialize. Just use Serializer.Serialize , .Merge and .Deserialize (etc).
That said; it does include some very under-developed and experimental support for this:
string proto = Serializer.GetProto<YourType>();
This is far from complete, but may work for simple types. If you have some specific cases where it fails, then let me know (add a comment or log an issue). However; most of the time, people interested in .proto would write the .proto first and work from there.
Examples of working decorated types are shown on the project home page; it is entirely up to you whether you use WCF attributes, xml attributes or protobuf-net attributes (although the latter provide more control over some specific serialization points, such as inheritance and numeric layouts).
Before Skeet Marc runs in here and gets massive ups, let me point out protobuf.net.
On a recent project we need to talk to a XML web service over HTTP. The project will run for a long time and we know that in that time the schema of the XML is likely to change some what although not drastically.
The service has a bunch of XSD files and we intend to generate out classes from these XSD's using xsd2code for Visual Studio.
I have a few thoughts/worries however. The names for the properties in the class are a little curt and I'd like to make them a bit more friendly, so instead of
private string ix_Rep_St { get; }
I'd rather it was something like:
private string BookingStatus
Even better I'd like it to have intellisense which I could add by editing the generated classes however as mentioned we are expecting these to change a little which could mean having to regenerate it all.
I'm after a way to end up with a set of classes that work with the service, yet are easy to code against (ie they use readable syntax) and have intellisense. I'm not sure how best to go about it.
My options seem to be:
Find away to separate out comments from the generated class file?
Generate everytime and put up with it, have some higher level classes interact with these nastily named ones from the service which should keep the mess contained.
Wrap all my classes in new human friendly wrappers with intellisense added in. Store the XSD's in source control and use that to highlight when something has changed then manually add it in
The wrapper sounds appealing if it where not for the amount of files I need to wrap, 30+ by my rough calculations which makes it feel like a bit of a slog.
Any pointers/ideas?
I want to mark many of my C# functions as "deprecated" or "needs work". My plan is to create customer attributes that I use to tag the functions. I saw this question which seems to indicate that information only attributes will not effect performance:
Is this use of attributes in .Net (C#) expensive?
My question is whether this is a bad use for attributes. Is there better way to mark code so that I can come back in phase 2 and either eliminate the code or rework it in some way?
P.S. I realize that there is an Obsolete attribute, but it results in far too many compiler warnings. I want to be able to see the "real" compiler warnings.
This feels like you want to create some sort of Project Management attributes for your classes.
I see project management as different than your code. If a feature is not 'done' right the first time, chances are it will be burried under other priorities and 'good enough' will cut it.
Of course there is always the Task list comments just add // TODO: and you will get it in your task list editor in visual studio if you do need reminders in your code.
I wouldn't go so far as to decorate classes with 'needfixing' attributes. If it's done it's done, if it's not it's not, if you need a reminder a todo should be enough.
I won't say that it's "bad" to mark code that needs work with attributes, but it may be overkill. Have you considered XML comments?
Could anyone explain the benefits (or reasons) to use custom attributes in your code. Of course I use (and understand the purpose of) defined attributes in certain scenarios (WCF, Serialization etc.), but I cannot imagine any algorithms where I would need to create and use my own custom attributes. Could someone provide a real-world case where usages of custom defined attributes bring something to a project.
The same reason as for WCF etc, but something that's specific to your project - you want to add some metadata to some members (types, fields, methods, whatever) to specify something about the mechanism involved, and it's not something which is covered by existing attributes.
For example, NUnit wanted to add their own indication that a particular type contained unit tests - there was no such existing attribute, so they created TestFixtureAttribute.
It's a relatively rare event, sure - but it can happen.
If you want to write your own system like WCF, Serialization, etc...
If you write code that iterates over types or members and does things with them, you will frequently want to use your own custom attributes to mark some members as being different or special.
I regularly use custom .Net attributes to support tooling in my infrastructure. One example was from very early in the .Net days (C# 1.0 to be exact). I was working on a research project which had a native C++ front and a brand new C# back end written by yours truly.
The front and back end shared a very similar object model which was evolving very rapidly. Not wanting to have to hand code both a C++ front end model, C++ serialization mechanism and a C# serialization mechanism I chose instead to attribute my C# types with custom attributes. They told me the parts of the model which were shared between the front and back end.
Once those attributes were in place I wrote a quick and dirty tool which
Parsed out the attributes to construct the core shared model
Generated the C# serialization code
Generated the C++ code
Generated the C++ serialization code
This made it dirt simple to keep my model up to date between my 2 projects. Just change the C# code, compile and re-run my tool.
I have used annotations in a custom AOP (Aspect-Oriented Programming) system I developed a while back. Attributes are also very useful for controlling orthogonal concerns like code generation.
Custom validation is a very good use case and can be seen from these links:
http://odetocode.com/blogs/scott/archive/2011/02/21/custom-data-annotation-validator-part-i-server-code.aspx
How to create Custom Data Annotation Validators
They can be used for marking tests, as in MBUnit for example. They can also be useful for code that inspects and loads classes (like a Plugin system) to provide meta-information.
They are really useful in building object mappers / ORM tools as well. If you ever decide to roll your own mapping system they are almost "required" to get all the functionality one would need. It's used more for making methods / classes more generic and using reflection to determine how to handle objects / select objects /etc...
To give you a specific case where I've used them. I once had to interact with a Mainframe screenscraper. I created a custom attribute to annotate which fields I wanted to send from my classes to the Mainframe, names that fell outside of conventions, special rules to deal with formatting and collections. I then had a class which was able to reflect over instances and realise which subset of fields were needed to interact with the mainframe screen scraper appropriately.
I have created a schema as an agreed upon interface between our company and an external company. I am now creating a WCF C# web service to handle the interface.
I ran the XSD utility and it created a C# class. The schema was built in BizTalk, and references other schemas, so all-in-all there are over 15 classes being generated.
I put [DataContract} attribute in front of each of the classes.
Do I have to put the [DataMember] attribute on every single property?
When I generate a test client program, the proxy does not have any code for any of these 15 classes.
We used to use this technique when using .asmx services, but not sure if it will work the same with WCF. If we change the schema, we would want to regenerate the WCF class, and then we would haev to each time redecorate it with all the [DataMember] attributes? Is there an newer tool similar to XSD.exe that will work better with WCF?
Thanks,
Neal Walters
SOLUTION (buried in one of Saunders answer/comments):
Add the XmlSerializerFormat to the Interface definition:
[OperationContract]
[XmlSerializerFormat] // ADD THIS LINE
Transaction SubmitTransaction(Transaction transactionIn);
Two notes:
1) After I did this, I saw a lot more .xsds in the my proxy (Service Reference) test client program, but I didn't see the new classes in my intellisense.
2) For some reason, until I did a build on the project, I didn't get all the classes in the intellisense (not sure why).
Neal, besides all the options John has given you, you should also check out the WCSF.blue tool on Codeplex: http://wscfblue.codeplex.com/
It's a "contract first" approach to doing WCF, and one of the many options it offers is to create a WCF DataContract file from your XSD:
This then pops up a dialog in which you can set a slew of parameters on how to create your C# class file from the XSD:
Quite useful, even if you want to use it for nothing more than converting XSD to C# classes that work as WCF DataContracts :-)
Also see this blog post for more explanations on the XSD DataContract generation process.
Classes that use [DataContract] will serialize to a very limited schema. For instance, there will be no attributes, only elements. This is intentional, and is done for performance and interoperability.
In general, a schema of the kind you may be working with may be much more complicated. Such a schema will not be usable with the Data Contract Serializer. You will need to use the XML Serializer instead.
In particular, don't edit the classes created by XSD.EXE. In fact, you should never edit generated code, as your edits will be removed as soon as the code is generated again. These classes should already have the attributes on them that will be needed for WCF to work with them.
What happens if you just use them as-is?
I'm shocked that no one pointed me to this utility, which I believe is what I was asking for:
http://msdn.microsoft.com/en-us/library/system.runtime.serialization.xsddatacontractimporter.aspx
I haven't tried it yet, but it looks like XsdDataContractImporter was what I was looking for, or the SVCUTIL with the /dataContractOnly flag.
I learned this when interviewing a candidate yesterday. She said DataContract serialization is faster and would be preferred to use.
Neal
Re: your XsdDataContract class mentioned in your followup, IMO, This is a niche class (as is ServiceContractGenerator etc) so i'm not surprised no one pointed you to it.
You still need to package it up to make it really useful. I'm pretty sure that code sample covers only very basic use cases so I would expect to do a lot of work with that to get it to a proper working state. . And like i mentioned on the WSCF forum, Svcutil, wscf, xsd.exe and others all use this class and related classes in the code gen process.
Regards the serializer performance, there are really good posts on Youssef Moussaoui's blog on the different serializers and their performance especially
http://blogs.msdn.com/youssefm/archive/2009/07/10/comparing-the-performance-of-net-serializers.aspx
There’s also a really good discussion here on Connect regarding the two serializers (XS and DCS) and a useful point that XS is still the way forward for WSDL/XSD First development as the DCS is only intended to support a simplified programming model and thus doesn’t support various xml constructs.
http://connect.microsoft.com/wcf/feedback/ViewFeedback.aspx?FeedbackID=451277
Hope this helps,
Cheers,
Benjy