Wcf端点自定义,用于简化配置

时间:2013-10-31 14:53:04

标签: .net wcf simplify wcf-endpoint wcf-configuration

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

这很好用并且给我们带来了很多麻烦,因为我们的客户端有一些逻辑可以自动构建指向同一个URL的端点。

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

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

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

1 个答案:

答案 0 :(得分: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的默认端点,并将其替换为自定义端点配置。例如,这里我只用合约2替换默认的“basicHttpBinding”和“WsHttpBinding”。你当然可以根据需要配置绑定(你提到了流媒体) - 这只是一个例子。

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测试客户端。

enter image description here