Timwi
Timwi

Reputation: 66604

How to create a WCF web service within an ASP.NET application that can return instances of an interface as a transparent proxy

My use-case:

Here’s what I tried (please tell me where I went wrong):

How do I fix this so that I get the IWorkInterface transparent proxy that I expect?

Things I’ve tried

What am I doing wrong?

Upvotes: 4

Views: 3336

Answers (3)

Timwi
Timwi

Reputation: 66604

The use-case I am describing is not directly supported by WCF.

The accepted work-around is to return an instance of EndpointAddress10 which points to the service for the “other” interface. The client must then manually create a Channel to access the remote object. WCF doesn’t properly encapsulate this process.

An example that demonstrates this is linked to from the MSDN article “From .NET Remoting to the Windows Communication Foundation (WCF)” (find the text that says “Click here to download the code sample for this article”). This example code demonstrates both .NET Remoting as well as WCF. It defines an interface that looks like this:

[ServiceContract]
public interface IRemoteFactory
{
    IMySessionBoundObject GetInstance();
    [OperationContract]
    EndpointAddress10 GetInstanceAddress();
}

Notice that the interface-returning method is not part of the contract, only the one that returns an EndpointAddress10 is marked with [OperationContract]. The example calls the first method via Remoting, where it correctly creates a remote proxy as one would expect — but when using WCF it resorts to the second method and then instantiates a separate ChannelFactory with the new endpoint address to access the new object.

Upvotes: 1

mclark1129
mclark1129

Reputation: 7592

What you are trying to do is a direct violation of the SOA Tenet: "Services share schema and contract, not class". What this means it that you don't actually pass implementation code from the service to its consumers, just the return values that are specified in the contract itself.

The main focus of WCF and SOA in general is interoperability, meaning services should be accessible to clients of any platform. How would a Java or C++ consumer be able to use this service you are designing? Short answer is that it couldn't, which is why you will find it difficult if not impossible to serialize this code over messaging standards like SOAP.

A more appropriate way to structure this code would be to host each implementation of IWorkerInterface as its own service (it has been defined as a service contract, after all), and expose each service on a different endpoint. Instead of MainService behaving as remote factory for proxies to an IWorkerInterface, it could act a as an endpoint factory to the different services you have set up. Endpoint metadata could easily be serialized and provided to the client by IMainService. The client could then take that metadata and construct a proxy to the remote implementation, either through some custom IServiceProxy implementation, or even through the objects already provided to you by WCF (such as the ChannelFactory).

Upvotes: 0

SliverNinja - MSFT
SliverNinja - MSFT

Reputation: 31651

What is MainServiceClient()? It is the class marshaling the client messages to the server.

You should take a look at a related SO post on returning interfaces as parameters in WCF. ServiceKnownTypeAttribute may be helpful.

Sessions may also be what you're looking for MarshalByRef as it relates to .NET Remoting behaviors.

Another approach (as mentioned on MSDN Forums) is to return the EndpointAddress of the service interface instead of the interface itself.

WCF does serialize everything - regardless of the binding. The best approach you should take if you need to communicate with the service on the same system is to use IPC transport binding (net.pipe).

Upvotes: 0

Related Questions