We want to have two .NET apps running on the same machine communicate with each other. We want three projects. A library containing interfaces. A "server" app that implements the interfaces and "client" app that communicates with the server using the interfaces. We do not want the client to reference the server.
We have a test app that does this with remoting but recently discovered that remoting is being replaced with WCF. Since this is new development we feel we should use WCF but we haven't managed to make it work with WCF and were wondering if it is possible?
EDIT:
Sorry for my lack of detail above but I didn't have access to any code at the time. I am working with two other people on this project and haven't looked closely at their IPC stuff. I know that they are currently of the opinion that WCF cannot do what they want it to do and I am hoping to be able to show them that it can.
I've started looking at my coworkers attempts at this and will continue to update this post as I understand it.
Below is a simplified version of their test code for remoting. They want to be able to do this using WCF but so far have been unable to get it to work.
- Lib\ IMessage.cs
- Lib\ IService.cs
- ServiceApp\ Service.cs
- ServiceApp\ ServiceMessage.cs
- ServiceApp\ ServiceProgram.cs
- ClientApp\ ClientProgram.cs
Both the ServiceApp and ClientApp assemblies reference the Lib assembly. They do not reference each other.
I will edit this again when I am better able to explain their attempt to replicate this behavior in WCF. At this point all I really know is that they are using NetNamedPipeBinding and are having trouble with the client app complaining that it cannot access the service assembly.
EDIT:
Below is a simplified version of the test code for WCF.
- Lib\ IMessage.cs
- Lib\ IService.cs
- ServiceApp\ Service.cs
- ServiceApp\ ServiceMessage.cs
- ServiceApp\ ServiceProgram.cs
- ClientApp\ ClientProgram.cs
The following line from ClientProgram throws an exception:
IMessage msg2 = service.CreateMessage("Hello World");
Here is the exception:
Could not load file or assembly 'ServiceApp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.
EDIT:
In trying to understand Steven's latest comment I googled IMetadataExchange which of course had as its first hit the MSDN Page. This page said:
There is no need to implement the MetadataReference contract in your service implementation. Instead, add the ServiceMetadataBehavior to the service description.
Or, when using configuration, set the contract attribute of the endpoint element to IMetadataExchange. For an example, see How to: Publish Metadata for a Service Using a Configuration File.
For details on publishing metadata in WCF see Publishing Metadata.
Because, for this example, I am not using configuration files but instead I choose to go to the Publishing Metadata link. From there I went to the How to: Publish Metadata for a Service Using Code link which had a nice example that I used to modify my service app code. The added code is on lines 15-20.
I was able to add the Service Reference after a little work. The service has to be running but if you run the service through Visual Studio then you don’t have the option to add the service reference. Also, I still don't understand how the "Discover Services in Solution" option is supposed to work. In the end I was able to add the reference by opening by bin/debug folder to manually run the service and then entering the URL I added to my service app. If this is the correct way it rather awkward.
After all of that the code generated doesn’t make any since to me. First off it recreates my IService interface but turns all my IMessages into objects and decorates it slightly differently. If their interface is used then not only will it be using a different IService then my service actually implements but the methods in this IService don't even have the same signatures!
Putting that aside I assumed I would have to change my client to use the objects from the newly generated object so I changed my client code.
Now when I attempt to run it I get the following error on line 4:
The formatter threw an exception while trying to deserialize the message: There was an error while trying to deserialize parameter http://tempuri.org/:msg. The InnerException message was 'XML 'Element' 'http://tempuri.org/:msg' does not contain expected attribute 'http://schemas.microsoft.com/2003/10/Serialization/:Type'. The deserializer has no knowledge of which type to deserialize. Check that the type being serialized has the same contract as the type being deserialized.'. Please see InnerException for more details.
EDIT:
One day left for the bounty and no answers since I added the bounty. Is there anything I can clarify before the bounty time is up?
EDIT:
In the end we went with remoting because it doesn't look as if what we want to do is possible with WCF. Steven Sudit gets the bounty for all his help despite the fact that it was all before I offered the bounty.