Reusing types across multiple webservices
Asked Answered
A

2

8

I have a collection of related webservices that share some of the types between them, notably the "token" generated by the TokenService.

When using "add reference" in Visual Studio, proxy classes are generated and many classes, such as the Token class, are duplicated for each webservice.

To resolve this I have written the following powershell script to generate .cs files for the webservices which reuse the types.

$svcutil = get-item ((get-item 'Env:\ProgramFiles(x86)').Value + "\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.1 Tools\x64\svcutil.exe")
$csc = "C:\Program Files (x86)\MSBuild\14.0\Bin\csc.exe"

& $svcutil "http://Path/to/WebService/WSTokenService?wsdl" /o:WSTokenService.cs
& $csc /target:library /out:temp.dll WSTokenService.cs

& $svcutil "http://Path/to/WebService/WSAssetService?wsdl" /r:temp.dll /o:WSAssetService.cs
& $csc /target:library /out:temp.dll WSTokenService.cs WSAssetService.cs 

& $svcutil "http://Path/to/WebService/WSContactService?wsdl" /r:temp.dll /o:WSContactService.cs
& $csc /target:library /out:temp.dll WSTokenService.cs WSAssetService.cs WSContactService.cs
..
repeat for 8 webservices

This "chains" the webservices together, resusing the shared classes, and seems to work.

Are there any problems with this approach and/or is there a better way to achieve sharing classes between the related webservices?

Edit: please note that these are not webservices developed by us and we do not have access to the code or classes that are used server-side.

Abbey answered 24/5, 2019 at 15:2 Comment(10)
Your project should be organized like THIS. ClassLibrary1 should contain all classes you want to share across services. WcfServiceLibrary1 is your service implementation. ClassLibrary2Proxy is where you are going to add your Service Reference ONLY ONCE in your entire SampleWcfSetup solution and generate your proxy for that particular service. ConsoleApp1 is your client app. Note that now you don't need to add a Service Reference here or anywhere else, as you would normally do for each client.Seamanship
All you need to do now is to add a using ClassLibrary2Proxy.ServiceReference1; in your source code.Seamanship
"ClassLibrary1 should contain all classes you want to share across services. ". So I should write these classes? They are usually generated from the WSDL(s).Abbey
If you are the owner of these services (and corresponding WSDL), then yes, of course you should and probably did write them. If you properly decorated these classes with DataContract and DataMember attributes, AND, they are part of your IService interfaces, then they will be picked up by svcutil and included in the namespace for the corresponding service.Seamanship
We are not the developers of these webservices - we are consuming them.Abbey
Well, there you have it... had the developers followed our advice...:O), it would've worked fine in both, YOUR APPROACH and OUR APPROACH. However, notice though, our approach is still a lot better because each proxy is in its own namespace, which is good because it allows you to selectively add a using only for the proxies you want...Seamanship
...And in your approach, as it stands, notice that both proxies are located in the same scope but outside any namespaces ... which first, is not standard .NET procedure, and second, does not allow you to include proxies selectively. And remember, like we mentioned before, in our approach you have to Add Reference only once in the entire solution, and that's it. So, which one are you gonna pick ?? :O)Seamanship
Forgot to mention: CompositeType is the boilerplate class being shared between services 1 and 2 in our example.Seamanship
I have uploaded a picture of what our object browser looks like for "shared types" using the approach above here: imgur.com/a/j26o8os . Since the consensus seems to be that we shouldn't do this I am going to revert back to not sharing types as it seems to make little practical difference besides forcing us to types some namespaces and/or use the var keyword..Abbey
And here's how object browser looks using "add reference" (without sharing types): imgur.com/a/9vRRQ5wAbbey
B
1

Why you did not create one class library project for sharing code between multiple solution? Or you can create project template for all of your microservices. I think, your current method is dirty and unsupported hack.

Borscht answered 24/5, 2019 at 15:54 Comment(1)
>create one class library project for sharing code between multiple solution I am making a class library for use in multiple solutions. This is not my problem. >you can create project template for all of your microservices I am not sure what you mean by this or how it would solve the problem. My problem is that if I use "add reference" then I get duplicate proxy classes. >your current method is dirty and unsupported hack Thanks. I am looking for for alternatives. I'm not sure this is unsupported - seems to work but I hope that there may be a more elegant solution.Abbey
H
0

I am making an assumption in my response that you are asking if the web services can share access to a single path where the DLL (library) is stored.

This is something that you can do in windows using the GAC (requires strong named assemblies) in order for multiple applications to have easy access to it. But to date I don't believe there is a comparable service available for micro-service architecture to do something similar.

So each web services requires it's own instance of the DLL in order to use the requisite internal code.

Hippie answered 30/5, 2019 at 16:8 Comment(3)
Sorry, I should have specified that these are not webservices developed by my team. We have URLs to connect to the webservices and are using either svcutil or "add reference" to generate c# classes to use the webservices.Abbey
Yep I understand, and you do that inside of each web service solution, and it generates the classes, and each web service ends up with a copy of it's own version of those classes etc. That's fine, there's really no better way of 'sharing' the references, at least not one that gives you any meaningful benefit.Hippie
"each web service ends up with a copy of it's own version of those classes etc. That's fine, there's really no better way of 'sharing' the references" You may be right. I was hoping for a comparable solution to using wsdl.exe with the /sharetypes parameter.Abbey

© 2022 - 2024 — McMap. All rights reserved.