How to return interface from WCF service?

Let's say I have some interfaces:

public interface IFoo { IBar DoesStuff(); } public interface IBar { string Thingo { get; } } 

I use this code throughout the code base. The IFoo process needs to be transferred to another system (difference x64 versus x32), this is our reason for using WFC. My WCF service implements this interface. When I create a "service link", proxy stubs are created, but the interface changes.

 public interface IFoo { object DoesStuff(); } 

I tried to define IBar / Bar as DataService and DataContract no difference. Is there a way to generate proxy code using my interface?

I think that if mock objects can create an object of my interface for testing, then can't I get a service to read it? Or did something stupid and wrong?

+4
source share
5 answers

IBar must be concrete and DataContract. WCF does not apply to distributed objects, but rather to a way to transfer data and how services work on that data. You cannot return an object to WCF with behavior.

+6
source

I do not know if you need a solution. Below I will do. The trick here is not to use the standard “add service links” as suggested by many blogs, but rather to create your own client proxy using Channel Factory. In this case, you can reuse your interfaces, but redefine specific classes if necessary. We are pleased to specify if you need.

 // Service Contract [ServiceContract(name="a", namespace="b")] public interface IFoo { Bar DoesStuff(); } // Interface to share public interface IBar { string Thingo { get; } } // Server Implementation public class Bar : IBar { string Thingo { get; set; } } // Client Proxy reference IBar interface only but redefine concrete class Bar. public class Bar : IBar { public string Thingo { get { return _thingo; } set { _thingo = value; } } string _thingo; } /// Sample channel factory implementation using System; using System.Configuration; using System.ServiceModel; using System.ServiceModel.Channels; public abstract partial class ServiceProxyBase<TServiceContract> : IServiceProxy where TServiceContract : class { protected ServiceProxyBase() : this(null, null) { } protected ServiceProxyBase(string url, Binding binding) { var contractName = typeof(TServiceContract).Name; var urlConfiguration = string.Format("{0}_Url", contractName); var serviceUrl = url ?? ConfigurationManager.AppSettings.ValueOrDefault (urlConfiguration, string.Empty, true); if (serviceUrl.IsNullOrEmptỵ̣()) { throw new Exception(string.Format("Unable to read configuration '{0}'", urlConfiguration)); } var serviceBinding = binding ?? new BasicHttpBinding(); Factory = new ChannelFactory<TServiceContract>(serviceBinding); var serviceUri = new Uri(serviceUrl); var endPoint = new EndpointAddress(serviceUri); Channel = Factory.CreateChannel(endPoint); } public virtual void Abort() { isAborted = true; } public virtual void Close() { if (Channel != null) { ((IClientChannel)Channel).Close(); } if (Factory != null) { Factory.Close(); } } private ChannelFactory<TServiceContract> Factory { get; set; } protected TServiceContract Channel { get; set; } private bool isAborted = false; } public class FooServiceProxy : ServiceProxyBase<IFooServiceProxy>, IFooServiceProxy { public Task<Bar> DoesStuffAsync() { return Channel.DoesStuffAsync(); } } [ServiceContract(name="a", namespace="b")] // The trick when redefine service contract public interface IFooServiceProxy { [OperationContract] Task<Bar> DoesStuffAsync(); } 
+2
source

Yes. Before adding a link to the service, you need to refer to the project containing the interface. Then the interface will be reused. The same will be true for any custom classes used - if a project containing their definitions refers to a client project before adding a service reference, then WCF can reuse these definitions.

You also need to go to the "Advanced" tab in the "Add Service Link" dialog box and check "Reuse Types in Reference Assemblies" to make it work.

+1
source

Try to think that web services are cross-platform. What would a Java client do with your interface if you returned it?

+1
source

Another way to trick a cat. Dominic did this using the KnownType attributes. Check out his blog below.

http://blogs.msdn.com/b/domgreen/archive/2009/04/13/wcf-using-interfaces-in-method-signatures.aspx

0
source

Source: https://habr.com/ru/post/1286715/


All Articles