I have Googled and read for hours, and I can not find anyone who is dealing with my specific scenario ...
I want to use the interfaces in my WCF service contracts to freely associate the service with the classes used on each end of the wire. This will allow us to have a low-level assembly containing only service and information contracts (only interfaces), which we can transfer to the consultant. At their end of the explorer, they can create instances of their data classes that implement our Data Contract interface, send it through the channel to us, and our WCF service will then broadcast / record / regardless of what incoming data in our version of the data class implements the same interface.
Here is an example. IDataContractcontains the information that I want to transmit via cable. Endpoints and other WCF-specific configurations are standard files (my problems may be this, so I can include more if I need to change something).
EDIT . I included more code and renamed a couple of classes to help it be less confusing. The additions of Name and Namespace to the DataContractAttributes, as well as two sections in the configuration files, are new additions based on information from this blog post . If I switch to an abstract base class instead of an interface, it works . However, I would like this to work with the interface, if possible.
Shared library (my code, together with the authors of the clients):
public interface IDataContract
{
string MyProperty { get; set; }
}
[ServiceContract]
public interface ITestService
{
[OperationContract]
IDataContract TestSharedInterface(IDataContract clientData);
}
():
[DataContract(Name = "IDataContract", Namespace = "http://services.sliderhouserules.com")]
public class ClientDataClass : IDataContract
{
[DataMember]
public string MyProperty { get; set; }
}
private static void CallTestSharedInterface()
{
EndpointAddress address = new EndpointAddress("http://localhost/ServiceContractsTest.WcfService/TestService.svc");
ChannelFactory<ITestService> factory = new ChannelFactory<ITestService>("ITestService", address);
ITestService proxy = factory.CreateChannel();
((IClientChannel)proxy).Open();
IDataContract clientData = new ClientDataClass() { MyProperty = "client data" };
IDataContract serverData = proxy.TestSharedInterface(clientData);
MessageBox.Show(serverData.MyProperty);
}
:
<system.runtime.serialization>
<dataContractSerializer>
<declaredTypes>
<add type="ServiceContractsTest.Contracts.DataContracts.IDataContract, ServiceContractsTest.Contracts">
<knownType type="ServiceContractsTest.WcfClient.ClientDataClass, ServiceContractsTest.WcfClient"/>
</add>
</declaredTypes>
</dataContractSerializer>
</system.runtime.serialization>
():
public class TestService : ITestService
{
public IDataContract TestSharedInterface(IDataContract clientData)
{
ServerDataClass convertedClientData = (ServerDataClass)clientData;
IDataContract serverData = new ServerDataClass() { MyProperty = convertedClientData.MyProperty + " + server data added" };
return serverData;
}
}
[DataContract(Name = "IDataContract", Namespace = "http://services.sliderhouserules.com")]
public class ServerDataClass : IDataContract
{
[DataMember]
public string MyProperty { get; set; }
}
:
<system.runtime.serialization>
<dataContractSerializer>
<declaredTypes>
<add type="ServiceContractsTest.Contracts.DataContracts.IDataContract, ServiceContractsTest.Contracts">
<knownType type="ServiceContractsTest.WcfService.ServerDataClass, ServiceContractsTest.WcfService"/>
</add>
</declaredTypes>
</dataContractSerializer>
</system.runtime.serialization>
, . ? , , , , , , , .
, ClientDataClass <IDataContract><MyProperty>client data</MyProperty></IDataContract>, ServerDataClass. , .