我有一个将由某个应用程序(当前网站)使用的Web服务。
这些电话几乎都是特定于某个客户的电话,但仍然是相同的。所以一个调用可能是getAllFoo(),但我需要一些参数来说明Foo来自哪个客户端。
如果我只是为所有调用添加一个标准参数,那么很快就会变得麻烦,所以我希望这样做有点DRY和自动。所有服务电话都会包含的内容。
IDispatchMessageInspector对我来说是正确的吗?可以包含哪些信息,我可以在方法中访问该信息吗?
我是否应该为调用创建某种属性?
如果有人能指出我的解决办法,那就太棒了。
修改
我正在考虑的另一个解决方案。
如果对特定客户端的服务调用发生在消费者端,则会在instanceCreation中知道,因此我可以使用已知客户端实例化ServiceClient。
我可以以某种方式将此解决方案用于ClientBase<>
扩展程序。
假设我正在为Domain1服务(让我们调用客户端域不要将它与服务客户端/消费者混淆)我创建了一个InformationProvider
消费者端,其中包含ClientBase<IInformationService>
字段。我确保在构造时设置了DomainName(domain1),因此在实例化ClientBase<IInformationService>
时我可以做同样的事情所以它以某种方式让服务知道我要求的域名。
我还在学习WCF
,所以我不确定如何做到这一点。
答案 0 :(得分:1)
我可以理解你想让你的解决方案变得简单而整洁,但最终 - 就像你自己说的那样 -
...我需要一些参数来说明哪个客户......
显而易见且最简单的解决方案是在需要的所有服务调用中包含client
参数。肯定会有不需要客户端参数的服务调用,在这种情况下,您不需要包含参数。
如果客户标识符被隐蔽地传递给客户标识符,您可以做一些聪明的事情,但要注意做一些不必要的聪明事情。我会将客户端作为一个简单的参数传递,因为它被用作参数。我想到了两个原因:
答案 1 :(得分:1)
可能的模式:
所涉及的步骤将是这样的:
[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerSession)]
public class MyService : IMyService
{
private int clientId;
public void StartUp(int clientId)
{
this.clientId = clientId;
然后是客户端,假设您使用生成的代理,将客户端包装在另一个代理中。
public class ExtendedClient : MyServiceClient
{
public ExtendedClient(int clientid) : base()
{
this.StartUp(clientid);
}
现在您应该实例化ExtendedClient,它将通过提供客户端ID来创建频道并启动服务。
我个人更喜欢简单地为每个服务调用发送客户端ID,但是如果你能够使用会话能力绑定,那么这应该可行。
关于WCF的一些信息。如果您有无状态服务,那么您需要将客户端作为参数包含在每个服务调用中。这不意味着您需要在整个代码中包含客户端 - 例如,您可以在ClientBase构造函数中检索它。但是您需要将它添加到每个OperationContract
和所有服务实现中。
另一种方法是拥有有状态服务 - 您首次使用的实例将保留供您重用(超时/例外除外)。在这种情况下,您可以只发送一次客户端,然后服务将了解客户端以进行后续调用。这是上述模式。这意味着您无法使用http绑定。我相信通过这样做,你只会增加应用程序中出现问题的可能性(有状态服务,必须确保初始化操作完成,进行更多服务调用)。