51

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

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

现在我想添加第二份(第 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();

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

4

8 回答 8

61

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

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

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

    #region IMyService2
    #endregion
}

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

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

// WcfEntryPoint.IMyService2.cs
public partial class WcfEntryPoint : IMyService2
{
    // IMyService2 methods
}
于 2008-12-02T16:22:32.503 回答
17

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

我将所有 WCF 服务托管在一个 Windows 服务中。

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);
    }

}

随意评论这种类型的设置,如果有任何问题,尤其是与性能相关的问题。

于 2009-08-17T16:39:37.370 回答
10

该答案是对来自chilltemp的已接受答案中的评论的进一步回应。

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

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

他没有提到合同实施的限制(我可以找到),但我无法想象他将服务上的 50 份合同视为类似于最佳实践的任何东西。我发现一种行之有效的解决方案是将成员共享用于类似功能。

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

希望这可以帮助。

于 2008-12-03T17:37:34.113 回答
9

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

于 2012-02-29T23:46:19.130 回答
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
}

编辑:正如马特所发布的,这将需要每个服务/合同的多个端点

于 2008-12-02T16:44:41.833 回答
3

没有人记录端点。当使用多个(作为一个组,来自公共 url,例如 http)必须使用相同的绑定实例(而不是更多),即

您的样品:

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();

应该只有一个 new Binding(),我在 http 上测试过。

servicehost = new ServiceHost(typeof(MyService1));
 BasicHttpBinding binding = new BasicHttpBinding();
servicehost.AddServiceEndpoint(typeof(IMyService1),binding , "http://127.0.0.1:800/MyApp/MyService1");
servicehost.AddServiceEndpoint(typeof(IMyService2), binding, "http://127.0.0.1:800/MyApp/MyService2");
servicehost.Open();

我完全同意部分类在少数文件中实现少数合同。

于 2015-09-19T08:05:43.447 回答
1

将其与基地址和下面的多个服务/合同分开呢?我现在不在开发机器后面,而是像:

http://myserver/myservices/serviceA
http://myserver/myservices/serviceB
http://myserver/myservices/serviceC

每个服务都实现自己的 ServiceContract。

您可以更改
public class WcfEntryPoint : IMyService1, IMyService2

public partial class WcfEntryPoint : IMyService1
public partial class WcfEntryPoint : IMyService2

例子

于 2009-08-19T09:49:24.293 回答
0

我错过了什么,还是这里没有提到最简单的解决方案?最简单的解决方案是:不要为 Web 服务使用多个接口。

但这并不意味着您仍然可以将接口分开。这就是我们有接口继承的原因。

[ServiceContract]
public interface IMetaSomeObjectService : ISomeObjectService1, ISomeObjectService2
{
}

Meta 接口继承自所有其他接口。

[ServiceContract]
public interface ISomeOjectService1
{
    [OperationContract]
    List<SomeOject> GetSomeObjects();
}

[ServiceContract]
public interface ISomeOjectService2
{
    [OperationContract]
    void DoSomethingElse();
}

然后服务只有 Meta 接口。

public class SomeObjectService : IMetaSomeObjectService
{
   public List<SomeOject> GetSomeObjects()
   {
       // code here
   }

   public void DoSomethingElse()
   {
       // code here
   }
}
于 2016-06-15T16:38:26.800 回答