Я не знаю, нужно ли вам еще решение. Ниже то, что я бы сделал. Хитрость здесь не в том, чтобы использовать стандартные «ссылки на сервисы», как предлагали многие блоги, а в том, чтобы написать собственный клиентский прокси с помощью 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();
}