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.
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:
- It solves the two issues stated above
- Only one file generated. (None of the VS generated garbage metadata files)
- No re-add of the ServiceReferences.ClientConfig file to the project.
- 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.
- 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">
- 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…
- 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…
Thanks for the post.
Try it again if you can.
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.
"
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
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...