1

我使用简化的配置(即<service>配置文件中没有显式节点),通过 IIS 公开的同一类实现了大量的服务合同。

这很好用并且为我们省去了很多麻烦,因为我们在客户端上有一些逻辑可以自动构建指向相同 url 的端点。

现在,我想在客户端和服务器上自定义其中一个合约,因为它的行为与其他合约完全不同。我想为这个特殊的合同类使用流传输,因为它既返回又获取Stream实例。

一旦我尝试<service>在服务器上添加一个节点,指向共享实现类并使用这个特殊的合同接口,其他服务的整个自动配置就会丢失,我只剩下一个暴露的服务。我认为这与我使用单个实现类这一事实有关,一旦 Wcf 检测到配置中存在具有该类名称的服务,它就会停止为其他合同自动生成端点。

有没有办法让这项工作,仍然共享同一个类并保持简化的配置?

4

1 回答 1

1

您可以通过创建自己的服务工厂并覆盖激活过程的某些部分来做到这一点。

假设您有两个这样的服务合同。

public interface IService1
{
    [OperationContract]
    string GetData(int value);
}

[ServiceContract]
public interface IService2
{
    [OperationContract]
    string Foobar();
}

假设这些是在这样的单个类中实现的。

public class Service1 : IService1, IService2
{
    public string GetData(int value)
    {
        return string.Format("You entered: {0}", value);
    }
    public string Foobar()
    {
        return "foobar";
    }
}

现在,如果您只想更改第二个服务合同的端点,那么在您的 .svc 文件中,添加 Factory 属性以指向自定义服务工厂实现。

<%@ ServiceHost Language="C#" Debug="true" Factory="SimpleWCF2.MyServiceFactory" Service="SimpleWCF2.Service1" CodeBehind="Service1.svc.cs" %>

接下来,创建一个实例化自定义服务主机的自定义服务工厂。在自定义服务主机中,覆盖 ApplyConfiguration 并删除合约 2 的默认端点,并将其替换为自定义端点配置。例如,这里我将默认的“basicHttpBinding”替换为“WsHttpBinding”,仅用于合同 2。当然,您可以根据需要配置绑定(您提到了流式传输)——这只是一个示例。

public class MyServiceFactory : ServiceHostFactory
{
    protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
    {
        return new MyServiceHost(serviceType, baseAddresses);
    }
}

public class MyServiceHost : ServiceHost
{
    public MyServiceHost(Type serviceType, params Uri[] baseAddresses) :
        base (serviceType, baseAddresses)
    { }

    protected override void ApplyConfiguration()
    {
        base.ApplyConfiguration();

        AddDefaultEndpoints();

        // Remove the default endpoint for IService2
        var defaultEp = this.Description.Endpoints.FirstOrDefault(e => e.Contract.ContractType == typeof(IService2));
        this.Description.Endpoints.Remove(defaultEp);

        // Add a new custom endpoint for IService2
        this.AddServiceEndpoint(typeof(IService2), new WSHttpBinding(), "test");
    }
}

而已。无需更改您的简化配置。

现在,您的客户端将通过新的服务端点发现第二个合同。例如,这是我的示例中的 WCF 测试客户端。

在此处输入图像描述

于 2013-11-01T03:02:43.010 回答