3

Visual Studio and SvcUtil can be used to generate proxy code to integrate with a service. In VS 2010 and prior there were issues if you wanted to maintain a cross tier reference library of shared types. This forced several workarounds to address the issue of equivalence in the data contract types and the inability to properly use the local types.

URL Reference to Issue: WCF Client Code Generation - Issue with "Reuse types from referenced assemblies"

I am using Visual Studio 2012, ASP.NET 4.5, C# code

My Question: "Has the reuse of types across assemblies been fixed in VS 2012?" I am porting over some code now but am also concerned that this bug may rear its head. I can run test cases, but it would be faster if someone had an answer already. It has been my experience that if you can not seem to find the answer online (googled it and keep getting 2011 - problem still exists) that the a fix may not be in place.

My Goal: Allow my future development team to reuse the same types library across the corporate .Net application tiers and layers [Presentation (Website, Mobile App layer - server side, ...), Domain (Services, Business Logic Layer, Data Access Layer)]. I would like to ensure some uniformity and code reuse. Code will be as "loosely coupled" as possible in each layer, but types will be ensured via the reference assembly. Equally, I want the code to support external integration for third parties down the road. Thus my need to construct all proxy types from DataContractAttribute decorated types for outward facing services and maintain referenced types for my server side applications.

Am I going to run into any quagmires here? Is the issue in the link above been addressed? Please advise.

Zack Jannsen
  • 622
  • 7
  • 17

2 Answers2

4

The bug which you report as existing in Reuse types from referenced assemblies option happens because by specifying re-use VS calls svcutil.exe under the hood with the /r flag.

However, svcutil.exe uses DataContractSerializer to help generate code and unfortunately this has a rather strict set of rules when it comes to parsing your service contracts.

So unless you service XSDs adhere to this set of rules svcutil.exe will switch to use the XmlSerializer, which doesn't support the /r flag (or re-use). Hence you will not be able to re-use types.

If you can reference the actual service contract types (via binary reference) this is a much better solution as you can do away with service references all together. You can also use WSCF.blue to generate your service contracts, as this has it's own custom serializer and supports re-use of types.

tom redfern
  • 30,562
  • 14
  • 91
  • 126
  • So far, thanks. +1 for the references. I see the hangup a bit clearer now. In terms of the architecture, I am building the tool to communicate internally via TCP, but do expect external clients down the road (thus the desire to support HTTP/HTTPS protocols. For the initial local service I expect I migh be able to make use of the binary references as the client and service will be .NET (at least initially). Do you have any reference to this in practice? I know WCF honors "equivolence" in data contracts so in theory it should support types with the same name and params. – Zack Jannsen Dec 20 '12 at 15:55
  • 2
    To call a service interface which you have a binary reference for you can use ChannelFactory, as described here: http://stackoverflow.com/a/8869809/569662. Yes WCF does support equivalence so you could prepare a strong named version of your service interface assembly and ship it to external consumers as a kind of API. It depends if your consumers will be .net or not. If not you will have to expose your types over WSDL. – tom redfern Dec 20 '12 at 16:05
  • To this end - I do expect to use "binary encoding" in the data center / farm. I expect use of "text / XML encoding" for outward facing components at a later date (e.g. company ERP integration). Furthermroe, wouldn't binary references increase coupling? As this app is human response time relative "scalability" is number one. I would opt for future interchaneability and load balance across instances. In this use case would you still support "binary references"? – Zack Jannsen Dec 20 '12 at 16:07
  • ChannelFactory / ChannelFactory was my expectation. Another point for the validation. Thank you sir. Whish I could give you more for the API comment. Worth considering. – Zack Jannsen Dec 20 '12 at 16:09
  • 1
    Re your comment: yes coupling is created by the binary dependency. – tom redfern Dec 20 '12 at 16:29
  • question on calling Channel.Open() ... most tutorials do not add that to the encapsulated Client (proxy) methods. Using TCP and ChannelFactory.CreateChannel would still require a call to open, correct? – Zack Jannsen Oct 30 '13 at 12:07
  • also, if you have access to the contract in a shared library ... you don't need to call ChannelFactory.Open ... do you? – Zack Jannsen Oct 30 '13 at 12:10
  • 1
    @ZackJannsen you do not need to call open on the channel if you are using ChannelFactory.CreateChannel() – tom redfern Oct 30 '13 at 12:42
  • What if you are looking to take advantage of "Async" capabilities? – Zack Jannsen Oct 30 '13 at 12:45
  • 1
    This is more difficult. I have not done this before. The only time I used this is with the pre-generated client from svcutil. – tom redfern Oct 30 '13 at 12:47
  • okay. Thanks. I am just assembling a library for WCF Infrastructure with client classes to make this re-usable. covering all bases. Thanks for the feedback. – Zack Jannsen Oct 30 '13 at 13:31
  • How about security. I am looking to "deny" execution of files in the repository. Files do save and I can distribute the file system, but when I assign user permissions (to my test account and the Admin account - Windows 7), then go to test it, it makes the directories, but fails to save the file. I am running a self made Windows forms test application, service is running, but I get "access to path ... is denied" errors. Is this a timing issue on filesys creation, or does VS2012 use a different account than 'logged in user' to run the client? – Zack Jannsen Nov 02 '13 at 15:46
  • By the way - everything else you said works perfectly. Thanks! If I could give you more plusses I would. – Zack Jannsen Nov 02 '13 at 15:46
  • I added the above security question to a new posted question if you care to try your hand at an answer: http://stackoverflow.com/questions/19744058/wcf-file-repository-and-security-error-in-permissions-on-saving-file – Zack Jannsen Nov 02 '13 at 16:33
2

In my situation both WebService and WebApp referenced the same assembly containing domain entities. Naturally, each entity was decorated with DataContractAttribute but when generating a ServiceReference in WebApp using an endpoint exposed by the WebService the Reuse Type in Referenced Assemblies had been seemingly ignored by VS2012, which resulted in additional copies of the types in the local assembly. Then (after several hours of trial and error) I added a Namespace parameter to the ServiceContractAttribute of my interface in WebService. Once added, the reparsed ServiceReference started to reference my shared DataContract types as desired.

 [ServiceContract(Namespace="http://www.example.com/Demo.WebService/")]
 public interface IConfigurationService { ..methods here.. }
timmi4sa
  • 594
  • 6
  • 15
  • Yes. It is recommended to explicitly set the namespace. Otherwise you end up with the default value "http://tempuri.org/" which is what you were experiencing. – Zack Jannsen Aug 22 '13 at 16:08