从WCF中的通用契约继承

更多WCF的困扰...... :)

我所有的工作流程都实现了相同的3种方法。 经过大量的复制和粘贴之后,我决定让它们从相同的接口继承:

[ServiceContract(Namespace = "http://schema.company.com/messages/")]
public interface IBasicContract<TRequest, TResponse>
  where TRequest : class
  where TResponse : class
{
  [OperationContract(Name = "GetReport",
    Action = "http://schema.company.com/messages/GetReport",
    ReplyAction = "http://schema.company.com/messages/GetReportResponse")]
  TResponse GetReport(TRequest inquiry);

  [OperationContract(Name = "GetRawReport",
    Action = "http://schema.company.com/messages/GetRawReport",
    ReplyAction = "http://schema.company.com/messages/GetRawReportResponse")]
  string GetRawReport(string guid);

  [OperationContract(Name = "GetArchiveReport",
    Action = "http://schema.company.com/messages/GetArchiveReport",
    ReplyAction = "http://schema.company.com/messages/GetArchiveReportResponse")]
  TResponse GetArchiveReport(string guid);
}

我还决定创建一个服务客户端的通用实现:

public class BasicSvcClient<TRequest, TResponse> : ClientBase<IBasicContract<TRequest, TResponse>>, IBasicContract<TRequest, TResponse>
  where TRequest : class
  where TResponse : class
{
  public BasicSvcClient()
  {
  }

  public BasicSvcClient(string endpointConfigurationName) :
    base(endpointConfigurationName)
  {
  }

  public BasicSvcClient(string endpointConfigurationName, string remoteAddress) :
    base(endpointConfigurationName, remoteAddress)
  {
  }

  public BasicSvcClient(string endpointConfigurationName, EndpointAddress remoteAddress) :
    base(endpointConfigurationName, remoteAddress)
  {
  }

  public BasicSvcClient(Binding binding, EndpointAddress remoteAddress) :
    base(binding, remoteAddress)
  {
  }

  public TResponse GetReport(TRequest inquiry)
  {
    return Channel.GetReport(inquiry);
  }

  public string GetRawReport(string guid)
  {
    return Channel.GetRawReport(guid);
  }

  public TResponse GetArchiveReport(string guid)
  {
    return Channel.GetArchiveReport(guid);
  }
}

问题是当我尝试使用这个:

using (var client = new BasicSvcClient<TRequest, TResponse>())
{
  var response = client.GetReport(inquiry);

  context.Response.ContentType = "text/xml";
  context.Response.Write(response.AsXML());
}

我总是收到一个错误消息,说它无法找到合同IBasicContract的配置,这是.NET使用的奇怪语法:

找不到引用合同'BasicWorkflow.IBasicContract`2的默认端点元素...

我试过这样做:

using (var client = new BasicSvcClient<TRequest, TResponse>("myConfig"))

它没有帮助 - 它仍然在寻找具体合同。

我知道ServiceContract属性有一个ConfigurationName参数,但是我不能在编译时使用它,因为我有很多我从同一个程序调用的工作流(因此也有很多配置条目)。 有没有办法在运行时设置ConfigurationName? 我认为这就是ClientBase构造函数应该做的,但显然不是。

[编辑]这是.config文件中的端点,我不认为这在这种情况下非常有用:

<endpoint address="https://localhost/services/Contract.svc"
    binding="basicHttpBinding"
    bindingConfiguration="httpsDataEndpoint"
    contract="IContract" name="IContractSvc" />

[编辑2]好的...我发现了一种可行的方式,但我仍然不完全满意:

using (var wf = new BasicSvcClient<TRequest, TResponse>(
  new BasicHttpBinding("httpsDataEndpoint"),
  new EndpointAddress("https://localhost/services/Contract.svc")))

我现在唯一的问题是我更喜欢从.config文件中检索端点地址(使用实际合同名称,如IContract)。 任何人可以帮助我的那部分?

[Edit3]终于找到了完整的解决方案:)万岁反光板!

var cf = (ClientSection) ConfigurationManager.GetSection("system.serviceModel/client");
foreach (ChannelEndpointElement endpoint in cf.Endpoints)
{
  if (endpoint.Name != "ContractSvc")
    continue;

  using (var wf = new BasicSvcClient<TRequest, TResponse>(
    new BasicHttpBinding("httpsDataEndpoint"),
    new EndpointAddress(endpoint.Address.ToString())))
  {
      //... call wf.GetReport()
  }
  break;
}

“.NET使用的奇怪语法”实际上是绑定到特定类型的泛型类型在运行时的类型名称。 Typename`n [[Type],...]其中n表示泛型中包含的类型参数的数量。

您的端点配置如何看起来像?


为什么不在ServiceContract属性中为合同指定一个名称:

[
ServiceContract
   (
    Namespace = "http://schema.company.com/messages/", 
    Name="MyBasicContract"
    )
]

如果你没有明确地指定一个名字,那么它将默认为你的接口的限定名称,它是“.NET使用的那种奇怪的语法”。


如果您想使用服务合同(如IBasicContract),则必须使用在配置文件中定义泛型类型的标准方法

它是这样写在配置文件中的:IBasicContract`2 [TRequest,TResponse]

我也在我的博客(www.lybecker.com/blog/)上回复了你的问题。

:-)安德斯李贝克

链接地址: http://www.djcxy.com/p/42663.html

上一篇: Inheriting from a generic contract in WCF

下一篇: how to repackage eclipse for my team