Developing on Staxmanade

T4 replacement for “Add Service Reference”

My company has been developing out parts of our website using Silverlight to enable some rich client LOB scenarios. Since the companies inception, we developed in a Scrum/Agile manner 3-6 week iterations. However, recently we started experimenting with a more “feature driven” attempt at “lean” approach.

With this new development approach, we made the decision that the trunk of the project’s source will be ready to deploy to production at all times. And as such would develop features out on branches. This is where the problem lies… We started running into a “Maximum file path length…” issue when branching the source. It’s a relatively old project (5 years or so now) with layers of projects/namespaces.

We traced the issue down to files generated by the Visual Studio’s Add Service Reference dialog.
image image

In our case the generated files had the full namespace + service name which were, in some cases, greater than 90 characters long just for the file. Coupled with the fact they were already nested in a directory structure (that helped keep things organized). We ended bumping into the “Maximum file path length…” when trying to branch the project.

After researching a hunch I’d had

Most of those files generated by the tool are garbage and never used, so why does VS generate them, and have to check them into TFS?

Here’s a good post describing the meta data files.
http://www.scottseely.com/blog/09-01-26/Misunderstood_Add_Service_Reference.aspx

I found out that the only thing we cared about was the “References.cs” file in that whole batch of files.

Now, we would like to, and have thought about writing our own code in place of using the VS generated, (I know I’ve heard from the WCF pros at IDesign that you should never use the “Add Service Reference” generated stuff…) however it does what we need with the exception of the super long file names generated and…every time we update the service reference it keeps trying to add the ServiceReferences.ClientConfig back into the project. Since we are not using a config file to store the WCF connection information. We are following a similar path you can read about here (http://geekswithblogs.net/mwatson/archive/2009/02/24/129655.aspx) This way we don’t have to have separate configs for Dev/Test/Production.

The built in VS Service Reference tooling has become more of a hindrance to development than providing any benefit.

What is the solution we came up with to these two issues?

What were the problems again?

1. Files generated by “Add Service Reference” tools are too long for TFS (Not the fault of the tool, more the fault of the (TFS/.net api/win api) for not supporting longer file names…

2. Every time we update/add new service reference it tries to re-add the ServiceReferences.ClientConfig file (DON”T WANT THAT)

After about 1/2 a day looking for alternatives to using the built in tool, and since the wcf svcutil doesn’t generate code Silverlight can use. I stumbled upon this blog Command line WCF Proxy Generation for Silverlight 2 RTM where he figured out how to use the same dll VS uses to generate the source and wrapped it into a little console app… After chatting w/ him on his blog’s Live Messenger plugin, (very cool by the way) he emailed me the exe he’s using in his production app (that had a couple bug fixes since his original blog post. He told me just to use Reflector to get at the source because it was very basic.

And so I did, and ended up with a pretty good solution to the problems above. (Sucks that I spent a day of dev time on this crap, but oh well…)

I wrote a T4 template that will generate all the reference.cs code needed in our Silverlight project. Instead of describing the template itself (since this post has gotten long alredy) I’ll include a project with a sample of how it works.

Some of the features you get using this template are:

  1. It solves the two issues stated above
    1. Only one file generated.  (None of the VS generated garbage metadata files)
    2. No re-add of the ServiceReferences.ClientConfig file to the project.
  2. With the use of the T4 template (this is in our app, not in the sample below) you can put other logic needed when generating a service reference.
    1. We are using it to update the Web.Config’s WCF aspnet compatibility flag so we can get at the wsdl and setting it back when done updating the service reference…
      <serviceHostingEnvironment aspNetCompatibilityEnabled="true">
  3. You can set some properties that will tell the tool to generate the types as “internal” (if you want)

    Note: you have to add the correct InternalsVisibleTo for this to work

    [assembly: System.Runtime.CompilerServices.InternalsVisibleTo("System.Runtime.Serialization")]

Here’s the sample project with examples of both a normal reference, and the same reference using the T4 template.

DOWNLOAD SAMPLE PROJECT

Hope this helps someone else…

Comments

Mega
How to reuse types in referenced assemblies ?
Jason.Jarrett
Nice! Thanks for the feedback!
Chris
This was great. We used the concept to modify the code dom and add DebuggerNonUser code attributes to every class. This allowed us to ignore the web service proxies when performing code coverage.

Thanks for the post.
Jason.Jarrett
I just tried it and it appears to be working (possibly you ran into a temporary skydrive issue?)

Try it again if you can.
Anonymous
than you for the article.
But the skydrive link doesn't work.
I allways end up with
"There's a temporary problem

There's a temporary problem with the service. Please try again. If you continue to get this message, try again later.
"
Anonymous
Jason,

Awesome post, thanks. I just figured out that i couldn't use overloading on my wcf service methods. But if you create the reference.cs your self it is possible. But writing the whole service ref. is to time-costly. This is the perfect solution for that. Thanks for posting!

Vincent Ottens
Jason.Jarrett
James,

I'm not sure what you're asking. If you read up on T4 templates, you should be able to find out that you can put any logic you want in there...
James
Great post, thanks. I'm interested in putting in custom logic, as you mentioned, but not sure where to start via the source provided...can you point me in the right direction? Thanks.
Anonymous
Can you please provide a VS 2010 Beta 2 sample of this, I tried but I can't get it to work, looks really promising thouhg.
Voleti
This is very useful. I was trying to figure out whether or not use Add Service Reference. Got some questions answered here. Thanks.