我不知道你是否还需要解决方案。下面是我要做的。这里的技巧不是像许多博客建议的那样使用标准的“添加服务引用”,而是使用 Channel Factory 编写自己的客户端代理。在这种情况下,您可以选择重用接口,但根据需要重新定义具体类。如果您需要,很乐意进一步详细说明。
// 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();
}