使用单一合同运行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传递 - 所以我可以为我的服务添加很多端点,但是所有端点都必须使用相同的合同,因为我只能提供一种实施方式? 我觉得我在这里错过了重点。当然必须有一些方法来为我添加的每个端点合同提供实现吗?
答案 0 :(得分:59)
您需要在同一个类中实现这两个服务(接口)。
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
}
答案 1 :(得分: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);
}
}
随意评论此类设置,如果有任何问题,尤其是与性能相关的问题。
答案 2 :(得分: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),分(X,Y)。如果将这些组合成更通用的成员并使用对象传递所需的数据,则可以轻松减少成员数并提高可伸缩性。示例:PeformCalculation(obj)其中obj具有x,y和action(加,减,乘,除)属性。
希望这有帮助。
答案 3 :(得分:8)
我通过使用RoutingService类找到了解决此问题的另一种解决方案。每个合同仍然必须托管在其自己的ServiceHost
中,但可以在所有合同之上放置RoutingService
- 并通过统一的#34;端点&#34呈现它们;。我还写了一篇关于它的codeproject article。示例代码也可以在Bitbucket上找到。
答案 4 :(得分: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
}
编辑:正如Matt发布的那样,每个服务/合同需要多个端点
答案 5 :(得分:3)
没有人记录的观点。使用多个(作为一个组,来自普通网址,例如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();
应该只有一个新的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();
我完全同意部分类在几个文件中实现少量合同。
答案 6 :(得分: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
答案 7 :(得分: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
}
}