使用多个合同运行WCF ServiceHost

Sam*_*Sam 51 wcf self-hosting

使用单个合同运行ServiceHost工作正常,如下所示:

servicehost = new ServiceHost(typeof(MyService1));
servicehost.AddServiceEndpoint(typeof(IMyService1), new NetTcpBinding(), "net.tcp://127.0.0.1:800/MyApp/MyService1");
servicehost.Open();
Run Code Online (Sandbox Code Playgroud)

现在我想添加第二个(第3个,第4个......)合同.我的第一个猜测就是添加更多端点,如下所示:

servicehost = new ServiceHost(typeof(MyService1));
servicehost.AddServiceEndpoint(typeof(IMyService1), new NetTcpBinding(), "net.tcp://127.0.0.1:800/MyApp/MyService1");
servicehost.AddServiceEndpoint(typeof(IMyService2), new NetTcpBinding(), "net.tcp://127.0.0.1:800/MyApp/MyService2");
servicehost.Open();
Run Code Online (Sandbox Code Playgroud)

但当然这不起作用,因为在ServiceHost的创建中我可以将MyService1作为参数或MyService2传递 - 所以我可以为我的服务添加很多端点,但所有必须使用相同的合同,因为我只能提供一个实现?
我觉得我在这里错过了重点.当然必须有一些方法来为我添加的每个端点合同提供实现吗?

chi*_*emp 60

您需要在同一个类中实现这两个服务(接口).

servicehost = new ServiceHost(typeof(WcfEntryPoint));
servicehost.Open(); 

public class WcfEntryPoint : IMyService1, IMyService2
{
    #region IMyService1
    #endregion

    #region IMyService2
    #endregion
}
Run Code Online (Sandbox Code Playgroud)

仅供参考:我经常使用部分类来使我的宿主类代码更容易阅读:

// WcfEntryPoint.IMyService1.cs
public partial class WcfEntryPoint : IMyService1
{
    // IMyService1 methods
}

// WcfEntryPoint.IMyService2.cs
public partial class WcfEntryPoint : IMyService2
{
    // IMyService2 methods
}
Run Code Online (Sandbox Code Playgroud)

  • 荡.我需要的不仅仅是2个服务合同,我猜10-50,对于这个数字,这种方法有点麻烦 - 将所有入口点放在一个单独的类中并不是很有帮助:(不是没有别的办法? (11认同)
  • 嗯,伙计们,你们都在谈论与我完全不同的东西.我需要10-50份合同*因为*我试图将每份合同的成员减少到3-5.我猜你的'合同'与'成员'混淆了. (2认同)
  • 您正在谈论让单个服务通过WCF公开最多250个成员.如果从不同角度处理解决方案,我认为你应该能够减少总计数. (2认同)

Saa*_*ail 17

我目前面临同样的问题,并决定采用下面的实施.我不确定是否有这么多服务合同存在任何性能问题,但在我的最终实现中,我可能会有大约10-15个服务合同,因此大约有10-15个ServiceHosts.

我在一个Windows服务中托管我的所有WCF服务.

private void PublishWcfEndpoints()
{
    var mappings = new Dictionary<Type, Type>
    {
       {typeof (IAuthenticationService), typeof (AuthenticationService)},
       {typeof(IUserService), typeof(UserService)},
       {typeof(IClientService), typeof(ClientService)}
    };


    foreach (var type in mappings)
    {
        Type contractType = type.Key;
        Type implementationType = type.Value;

        ServiceHost serviceHost = new ServiceHost(implementationType);
        ServiceEndpoint endpoint = serviceHost.AddServiceEndpoint(contractType, ServiceHelper.GetDefaultBinding(),
                                                                  Properties.Settings.Default.ServiceUrl  + "/" + contractType.Name);
        endpoint.Behaviors.Add(new ServerSessionBehavior());

        ServiceDebugBehavior serviceDebugBehaviour =
            serviceHost.Description.Behaviors.Find<ServiceDebugBehavior>();
        serviceDebugBehaviour.IncludeExceptionDetailInFaults = true;

        log.DebugFormat("Published Service endpoint: {0}", Properties.Settings.Default.ServiceUrl);

        serviceHost.Open();
        serviceHosts.Add(serviceHost);
    }

}
Run Code Online (Sandbox Code Playgroud)

请随意评论此类设置,如果有任何问题,尤其是与性能相关的问题.


Chr*_*ter 10

这个答案是对chilltemp接受的答案中的评论的进一步回应.

山姆,你真的应该确定为什么你需要10-50份合同并试图找到另一种解决方案.我查看了Juval Lowy的WCF编码标准(在http://www.idesign.net/找到)并找到了以下参考资料:

3服务合同 ...... 4.避免与一名成员签订合同.5.力争每份服务合同有三到五名成员.6.每份服务合同的成员不得超过20人.十二可能是实际限制.

他没有提到合同实施的限制(我可以找到),但我无法想象他在服务上查看50个合同,因为它们类似于最佳实践.我发现一个很好用的解决方案是使用成员共享来实现类似的功能.

例如,如果您使用WCF服务对2个值执行数学,则服务端可能有4个成员:Add(x,y),Subtract(x,y),Multiply(x,y),Divide(x ,Y).如果将这些组合成更通用的成员并使用对象传递所需的数据,则可以轻松减少成员数并提高可伸缩性.示例:PeformCalculation(obj)其中obj具有x,y和action(加,减,乘,除)属性.

希望这可以帮助.

  • 这不是混淆,他没有提到合同限制,但我不想走上拥有 50 份服务合同的道路。应该对您的合约进行某种形式的重构,以减少它们的大小/数量。它是您的应用程序,但我会寻找其他选项。 (2认同)

m0s*_*0sa 8

我通过使用RoutingService类找到了解决此问题的另一种方法.每个合同仍然必须由它自己托管ServiceHost,但可以在RoutingService所有合同之上 - 并通过统一的"端点"呈现它们.我还写了一篇关于它的代码项目文章.Bitbucket上也提供了示例代码.


Chr*_*ter 6

如果您对服务共享的合同感到满意,那么辣椒的答案将会奏效.如果你想让它们分开试试这个:

host1 = new ServiceHost(typeof(MyService1));
host2 = new ServiceHost(typeof(MyService2));

host1.Open();
host2.Open();

public class MyService1 : IMyService1
{
    #region IMyService1
    #endregion
}

public class MyService2 : IMyService2
{
    #region IMyService2
    #endregion
}
Run Code Online (Sandbox Code Playgroud)

编辑:正如Matt发布的那样,这将需要每个服务/合同的多个端点