在共享 mex 端点的单个 Windows 服务中动态托管多个 WCF 服务的最佳方法是什么?

发布于 2025-01-08 09:07:23 字数 861 浏览 0 评论 0原文

我收到一个请求,要求在单个 Windows 服务中动态托管多个 WCF 服务。

要求如下:

  • 服务是实现某些服务契约接口的单例实例。
  • 这些服务在编译时是未知的 - 在运行时,未知的单调服务的集合被传递到应用程序。
  • 所有服务都通过相同的 mex 端点公开
  • 端点以编程方式设置(不使用 app.config)

我尝试通过两种不同的方法解决问题:

  • 第一种方法是为每个服务实例创建并打开一个 ServiceHost。这种方法的问题是每个 ServiceHost 都通过自己的 mex 端点公开。
  • 第二种方法是为所有服务创建一个 ServiceHost,并通过相同的 mex 端点公开它们。

我尝试了几种方法来实现第二种方法:

  • 第一种方法是在运行时创建一个服务类型(使用 CodeDom 或 Reflection.Emit)来包装所有实例,并实现所有服务契约并将给定方法调用路由到合适的服务实例。这可行,但似乎有点矫枉过正。 (如果可能的话,我宁愿不生成代码)
  • 第二种方法是以编程方式为请求的合约设置 ServiceEndpoints。我修改了以下代码示例 因此它将把方法调用路由到相应服务实例的方法。此解决方案的问题在于,为了将 ServiceEndpoint 与其 ChannelDispatcher 相关联而进行了黑客攻击。

我错过了其他方法吗?有什么办法可以克服我提到的问题吗?

I have been given a request to dynamically host multiple WCF services in a single Windows service.

The requirements are the following:

  • The services are singletone instances implementing some service contract interfaces.
  • The services aren't known at compile-time - at runtime a collecion of unknown singletone services are passed to the application.
  • All services are exposed via the same mex endpoint
  • The endpoints are set programmatically (without using app.config)

I tried solving the problem from two different approaches:

  • The first approach is to create and open a ServiceHost for each service instance. The problem with this approach is that each ServiceHost is exposed via its own mex endpoint.
  • The second approach is to create a single ServiceHost for all services, and expose them all via the same mex endpoint.

I tried a couple of ways to implement the second approach:

  • The first way is to create a service type in runtime (using CodeDom or Reflection.Emit) that wraps all instances, and implements all of the service contracts and routes a given method call to the suitable service instance. This works but seems like a overkill. (I rather to not generate code if possible)
  • The second way is to programmatically setup ServiceEndpoints for requested contracts. I modified this following code example so it will route a method call to the corresponding service instance's method. The problem with this solution is that a hack is made in order to associate a ServiceEndpoint to its ChannelDispatcher.

Am I missing other approaches? Is there anyway to overcome the problems I mentioned?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

孤檠 2025-01-15 09:07:23

如果我正确理解您的问题,那么一种方法是在单个服务类中实现多个契约接口。通过这样做,您应该能够从单个 mex 端点获取元数据。这是一个非常简单的示例:

[ServiceContract]
public interface IServiceContract1
{
    [OperationContract]
    bool DoStuff1();
}
[ServiceContract]
public interface IServiceContract2
{
    [OperationContract]
    bool DoStuff2();
}

public class ServiceContractImplementation: IServiceContract1, IServiceContract2
{
    bool DoStuff1()
    {
        return true;
    }
    bool DoStuff2()
    {
        return true;
    }
}

然后在 web.config 中(或在您的情况下在代码中):

<service name="ServiceImplementation">
        <endpoint binding="basicHttpBinding" contract="IServiceContract1"/>
        <endpoint binding="basicHttpBinding" contract="IServiceContract2"/>
        <endpoint address="mex" contract="IMetadataExchange" />
      </service>

If I'm understanding your problem correctly, then one approach would be to implement multiple contract interfaces in a single service class. By doing that, you should be able to get the metadata from a single mex endpoint. Here's a very simple example:

[ServiceContract]
public interface IServiceContract1
{
    [OperationContract]
    bool DoStuff1();
}
[ServiceContract]
public interface IServiceContract2
{
    [OperationContract]
    bool DoStuff2();
}

public class ServiceContractImplementation: IServiceContract1, IServiceContract2
{
    bool DoStuff1()
    {
        return true;
    }
    bool DoStuff2()
    {
        return true;
    }
}

Then in the web.config (or in code in your case):

<service name="ServiceImplementation">
        <endpoint binding="basicHttpBinding" contract="IServiceContract1"/>
        <endpoint binding="basicHttpBinding" contract="IServiceContract2"/>
        <endpoint address="mex" contract="IMetadataExchange" />
      </service>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文