I have created a number of WCF Services, for arguments sake they are called Service1 and Service2.
Both of the services return (at some point, possibly through a relationship inside an object) a Customer object.
For testing sake, I have added a GetCustomer() method to both Service1 and Service2 and I have added a service reference to both services in a basic WinForms application.
Service1Client proxy1 = new Service1Client();
Customer customer1 = proxy1.GetCustomer(); //
^^^^^^ Ambiguous reference, requires me to name as WcfTestClient.Service1.Customer
Service2Client proxy2 = new Service2Client();
Customer customer2 = proxy2.GetCustomer();
^^^^^ Ambiguous reference, requires me to name as WcfTestClient.Service2.Customer
The problem is, the Customer object returned by Service1 and Service2 are both the same type of Customer (WcfTestService.Customer). To remedy this I need to include the full assembly name rather than just Customer.
I have read a few posts on Stack Overflow stating that it is possible to compile the Data Contracts into a separate assembly, I don’t particularly like this idea as it may still cause problems with clients using other languages, such as Java.
Another solution I have seen is the SvcUtil.exe method, but from what I have seen this solution doesn’t address my namespace issue as I need to run the Util for each service individually?
If anyone has any helpful suggestions, please get in touch!
Both of the services return (at some point, possibly through a relationship inside an object) a Customer object.
Here's where you're wrong. WCF doesn't return objects, REST doesn't return objects, SOAP doesn't return objects. They all pass messages.
Now what happens when you add a reference to a web service is Visual Studio happily creates a wrapper class for these messages, exposing their contents as properties, nothing more. Because you are adding two services these wrapper classes have no knowledge of each other and thus you end up with two namespaces and two wrapper classes.
Yes, as you say you could move the message classes to a separate assembly, link that and avoid Add Reference and that will then act as a proper object, but still behind the scenes it's messages being passed and serialized and deserialized into this shared object. Stop thinking in terms of object passing and start thinking in terms of messages and you'll realise you're either stuck with two wrapper objects, or you need to link an external assembly.
Related
I have 3 projects in my solution.
A common class library named ReportBuilderLib
A WPF application named ReportClient that contains a service reference to a 3rd project -
A WCF web service which contains web methods for my application to call upon.
Initially when setting up both the service and the application i added the common library to references on both projects so that i could use the classes i needed to in both.
It quickly cam clear that in the process of generating the code to use the web methods in my client application, it was automatically importing certain namespaces that i had used in service application.
This was throwing me conflicting reference warnings as they were effectively being imported from two separate resources.
I then removed the reference to the library in my report client, i could see that VS was only importing one out of the two namespaces my client requires. Both of which are returned by methods in my ServiceContract!
Having looked at the generated code for the client, it seems to be re-creating the classes i have included in the library and providing only the public properties for access.
Is it possible to use librarys like i am trying to with WCF. Or should i scrap the common library idea and simply create some data transfer classes on the service end?
You should be able to reference the common library on both ends, but it may be useful and less of a headache to implement data transfer classes like you suggested. Using special classes (or serialization like JSON) to send and receive data from the service would make it easier for you to re-use the service for multiple client projects.
Any time you decrease the coupling between layers of an application you make it easier to implement changes/upgrades in the future :)
I have tried googling for an answer since last week and haven't found anything. Maybe I'm just searching with incorrect key words...
Basically, we have a running WCF service and then we have a separate dll with another ServiceContract in it. We want to know if it is possible to expose the separate dll in the current running service and if one can, how?
We are still new to WCF, so please excuse if this is a stupid question. :(
We are working with .NET 3.5 SP1 and C#.
Regards
EDIT:
We want to separate our service into "modules". So the service implementations (Methods, ect) and contracts (Interfaces) are all in separate libraries. So lets say you have a module called "Clients". We want everything related to Clients to be in the same separate library (DLL) instead of one big base class that inherits from multiple interfaces. This is a huge service and we need multiple developers to work on different sections of the same service at the same time. This is what I've been instructed to figure out, but if it can be done then it can't. I hope this makes more sens??
Assuming you are asking how you can implement a service contract declared in one DLL in a service running in a separate DLL/Application:
Edits to match post edits
add a reference to the DLL with the service contract to the application containing the service
In the .cs file with service implmentation add a using statement for the namespace of the service contract
derive the service from the service contract (you will have problems if you define your service contracts as concrete classes rather than interfaces and you want to expose multiple contracts on your service
If self hosting then create a ServiceHost passing the type object of the service in the other assembly, if IIS hosting create an .svc file referencing the class in the other assembly as the service
Add a service element in the config file naming the fully qualified name of the service
Add an endpoint to the service at a unique address for the new contract
When you take the other assembly (dll) as a reference in the "main" project, then add a using directive to the file where the WCF service is instantiated. Then you can simply use the referenced service contract to set up a running service with the right endpoints and binding(configuration).
I guess one work around is you have a main ServiceHost hosting your WCFMainLib and then all your clients will connect to WCFMainLib.
WCFMainLib then acts like a proxy to connect to all other WCFModuleLib on localhost (or other servers) to fetch data.
WCFMainlib will implement the IWCFModuleLib1, IWCFModuleLib2 etc service contract interfaces and expose them to the WCFClient. Actual implementation of interfaces will then be a call to the actual WCFModuleLibs.
This may introduce some overhead, but overall also introduces several "features" that may benefit your boss or service availability.
OR, if you are just wanting to delegate programming work, maybe you can tell each team to work with partial classes for your WCFLib with each service contract on a partial class then do a nightly compile.
I have some member functions in three custom classes already created in my service. My objective is to use these custom classes on the client side to access the the member functions in the service. How do I expose these classes with all the member methods in them to the client?
I created these three classes in my service and marked them as "DataContract", and the member functions as "OperationContract". I created an Interface that defines these custom classes as OperationContracts returning an object of each of the classes through implementing them on a separate class.
Unfortunately, I couldn't achieve my objective because two of the classes have a constructor that takes some parameters, whereas the class with no constructor was accessible on the client side but I couldn't see the member methods in the class.
I need your hints on what to do.
That won't be easy to do. One way would be to share the DataContract-decorated types between the WCF server and its clients, i.e. add a reference to your service assembly in the client project and bind the service reference to that assembly reference.
However, that breaks contract implementation independence, as the exact same service assembly will need to exist on both the client and the server, and be kept synchronized every time it changes.
See here for more details.
By default and by design, WCF will only share contracts between client and server, e.g. your services ([ServiceContract]), their methods ([OperationContract]) and the data structures they operate on ([DataContract]).
WCF is a message passing system, so all the client and the server share in terms of the data being passed around is a XML serialized message format. When you add a service reference, the client-side proxy will generate a class for each [DataContract] that will look identical in XML serialized format - only the data is being moved back and forth - no behavior (no methods).
Basically, if you want to expose functionality, you need to have a service method decorated with a [OperationContract] attribute. Methods on your data classes will never be visible to the client - and that's by design.
If you control both ends of the communication and both are .NET based, you can "trick" your way around this limitation:
put all your service and data contracts into a separate class library assembly
use a reference to that common, shared assembly to create your service
before you do an Add Service Reference, add a reference to that common assembly on your client
In that case, the WCF runtime will reuse existing types from that common assembly, instead of re-creating them from the service description. And since that assembly contains the shared code that the server also uses, your classes also have their methods present.
It works ok in a .NET only scenario, but it's really kind of a dirty trick behind the proper service separation facade.
I have a class as DataContract in my webservice and it inherit from IEquatable.
But my siverlight webservice generated proxy class does not have equals. Can any one tell me why this is happening and is there a way achieve this?
WCF serializes only data from data contracts - no methods or behavior.
That's by default and by design - after all, WCF is a message passing system - you pass around serialized messages only.
WCF is NOT a "remote-procedure call" or "object remoting" system and thus, when creating a proxy, it will make sure the data signature on the wire will be identical (by means of XML serialization) - and that's all it does.
The only option to achieve what you're looking for would be to:
create a separate class library assembly that contains the service and data contract classes
reference that common contract assembly from both your server-side service code, as well as your client-side Silverlight app
when creating a service reference now, Visual Studio will reuse the common, shared classes in the assembly, and not re-create proxy data classes (and loosing the methods in the process)
Ok, not really sure how to word, but will try my best.
I have a number of WCF services that are setup and run awaiting an object to come in for processing.
WCFServiceA
WCFServiceB
WCFServiceC
Service A will run some processing and decide to send the object onto Service B or C.
So my object has [DataContract] attribute on all classes in it and [DataMember] on all properties.
So so far so good.
But now I well lose all the functionality from my object, as this is now basically a serialised version of the object.
So is it best practice if I want to use a full complex object to include the same assembly in all 3 services as a reference and send things across as "KnownTypes"?? Providing the basic DataContract and DataMember for anything using the services that does not know these types so they can still create these object for the services to run with?
Hope I have worded this correctly and you understand my question here.
:EDIT:
To try and clarify.
The object I am sending can have a "Policy" attached to it, this policy object is a class and can be one of several types, vehicle, house, life, pet policy etc.
But the actual type will not be known by the receiving service. Hence the need for KnownTypes.
I think I just answered my own question!! :)
That was a good explanation of the problem. The draw back I see in this approach is if you are going to update the object , say adding new properties or removing some , all the 3 service needs to be updated with the new assembly.
Using of the known types can sometimes lead to backward compatibility issues when you want to upgrade the objects in live depending on the setup.
Or create a DTO (Data transfer object) with just the properties and pass it across the services as a data contract and strip the complex logic in to a helper class which can be referenced by the services.