I am working with integrating an MVC4 application with WCF services. At present, I generate a service reference from the WCF services endpoint using svcutil.
I have a number of services eg. a BooksServiceReference and CarsServiceReference. An issue I have is that both service references share the same entities but my code treats them differently as they have different namespaces. For example, both references have a Price entity which is the same, only a different namespace.
What I want to do but unsure in doing is the follows. Use T4 mapping to take each class in the service reference file and generate a DTO object for it. So at this point, I have my own DTO object for all classes in the service reference.
Next step, exclude the common entities via a T4 configuration file that are common to both service references. I believe this will be manual and I am fine with this.
For the common entities to, I create a separate T4 configuration file which generates these in to one DTO file.
I have only done some brief work with T4 generation so would appreciate any assistance with the above?
Related
We are transitioning a WCF based solution over to use gRPC.
We require both the Service and Client code generation that the Grpc.Tools package provides. However, we need the Clients to target .NET Standard 2.0 for comparability reasons.
Services need to call other services, so those projects need to be able to consume both the service stubs and the client stubs.
We also don't really want the service stubs to be exposed to consumers just wanting to use the gRPC clients.
This is proving a challenging requirement to satisfy.
Trial 1:
Have two projects, both importing the same proto files, each set to generate either the Server or Client.
Problem: A consuming project can't reference both server and client project due to the generated messages having duplicate namespaces.
The C# namespace is defined in the proto file itself.
Trial 2:
Separate the proto files out into messages and services. Have a models project which only generates the messages into code.
Have the client and service projects reference the models project, and import the services proto files to have them generate the stubs they need.
Problem: gRPC generates the stubs inside of a static class, which again has the same namespace in both projects so a consumer is unable to determine which version to use.
I now have two routes I can go down.
Option A:
In both the client and server projects, create classes which inherit from the gRPC generated ones so they can be exposed onto a different namespace.
For the services, this isn't so bad. The clients however have two constructors and a instance generation method which would need to be brought over to the child class.
Option B:
Create duplicate proto files for the service definitions, one having a namespace for the service stub and the other having the namespace for the client stub.
Both options have their downsides. Option A is probably the least bad as it doesn't require two files to be manually kept in sync.
Does anyone have any alternative recommendations?
Ideally there would be a way to alter the namespace defined in the proto files somehow when using Grpc.Tools, but reading the documentation, there doesn't seem to be a way to do that.
In some projects when I add a service reference to a WCF service, it creates datasource files for classes shared in a common class library, however in others the datasources are not created. The Reference.cs file is different where in the first case the types are from the class library and in the latter it's in the Reference.cs file it self. These are not compatible.
What is it that triggers the automatic generation of the datasource files in this case? Advanced options in Add Service Reference dialog are identical so something else must be playing tricks on me.
UPDATE: Turns out the datasource files are not needed. It's the code generated in the Reference.cs file that makes the whole difference. I can manually edit the parameters for the methods to point to the class-library, and it works. This is of course not a solution in the long run, since I have to do this every time I update the Service Reference. Hopefully someone will come along who knows the trigger of this problem.
The file is created by VS when you add a service reference. It's used to enable client UI components to bind to the models (data contracts). I don't know why they are not created for "all" services (but I guess it depends on how that service defines and uses data contracts (as in: no contract no data file)).
Here are some useful links:
https://msdn.microsoft.com/en-us/library/ee373840.aspx
What are the WCF Service Reference .datasource files?
UPDATE: You are right it should not depend on the consumed service. Here are two related links (that impliece that the files are included by VS):
http://objectmix.com/dotnet/797048-wcf-service-reference-datasource-file-name-length-problem.html
Disable automatic generation of datasources file when updating service references
So it looks like the file is created by VS, if you don't wan/need it you can exclude it by creating the proxy with svcutil.exe
I have couple of WSDLs to refer from my project.
For the decoupling concerns I need to map the classes defined in service reference to my own classes.
Is there is any way or tool to generate these mapper classes instead of copy pasting?
AutoMapper is a convention-based mapping tool with a fluent API. It's specifically designed to handle mapping concerns in situations like this.
I've used it on a number of projects and been very happy with it.
You can use the Web Services Description Language Tool to generate the C# classes needed to interact with the web service.
wsdl /out:myProxyClass.cs http://host/WebService.asmx?WSDL
Or you can use the newer ServiceModel Metadata Utility Tool:
svcutil /t:code http://host/WebService.svc /out:myProxyClass.cs /config:myProxyClass.config
If necessary you can then modify these classes yourself.
I was able to download and include both the partner and enterprise WSDLs into my VS .NET 2010 project. In the Web References folder, all that appears is a Reference.map file, which, when I expand, exposes a few other .datasource files but no class stubs.
After including a reference to both APIs, I can not create an instance of my Salesforce classes (both native [such as Account] and custom). I need to do this for an upsert().
Is there something I am missing? Please help.
You don't typically need both the Partner and the Enterprise WSDL in the same project.
The Enterprise WSDL will be tailored to the schema of the generating Org and will have classes for Account, Contact etc and include properties for custom fields.
The Partner WSDL is designed to work with any Org, so it doesn't have specific classes. Instead you use a generic sObject and access XML Elements for the field values.
I have WSDL and XSD as starting point. (WSDL is generated from XSD using WCSF Blue tool). From the WSDL, using a tool, the service code is generated. The project name is “Autogenerated_Service_Project”. Inside this project it will have [ServiceContract] and [DataContract] classes. It has a data contract named “EmployeeDataContract”. In the GetEmployee() service operation, this datacontract is returned to the client.
I have a business layer project named “Business_Project”. It has a method that returns “Employee” entity object.
At present, I am referring the “Business_Project” inside “Autogenerated_Service_Project”.
Business_Project.MyClass b = new Business_Project.MyClass();
EmployeeDataContract d = b.GetAssociate();
return EmployeeDataContract;
The challenge comes when there happens a change in WSDl. When the WSDL is the changed the “Autogenerated_Service_Project” will be recreated and the code mentioned above will be lost.
What is the solution to overcome this code lose?
Note: The “Autogenerated_Service_Project” is the top most project. Ideally, it cannot be referred by any other projects.
You may change the way calling Business layer(may your solution needs additional layer)
But in simple way, you can generate the proxy once, when changes happen to WSDL
handle the changes manually,Or use the tool only for new services.
If the services on WSDL are finely grained, the solution may be applicable.
This can be resolved by using Partial Classes in a different file. The code given in the question can be moved to this new partial class file. This file will persist even if the auto generated file is re-created.