3

我有一个简单的应用程序,我使用 global.asax 通过 Application_Start 中的自定义 servicehostfactory 将 serviceroute 映射到 wcf 服务。该服务的构造函数会进行一些初始处理来设置需要一些时间的服务。

我需要这个构造函数在它的 serviceroute 被自动添加时触发。我尝试从 global.asax 创建一个客户端通道并进行虚拟调用以启动该服务,但发现该服务尚未启动 - 似乎 application_start 必须返回?

那么,如何在第一次通过 global.asax 映射时触发服务的构造函数,而无需手动点击服务?不幸的是 AppFabric 不是我们的选择,所以我不能只使用它的内置自动启动..

更新

我被要求提供更多细节;

这就像一个路由管理服务。所以我有 Service1——它被添加为 global.asax 中的服务路由。现在我有http://localhost/Service1

在 Service1 中,我有一个名为“addServiceRoute”的方法。调用时,它还会为 Service2 注册一个路由。现在我有http://localhost/Service1/Service2

我最初的 global.asax 解决方案是为http://localhost/service1构建一个 channelfactory ,但这不起作用。Service1 尚未启动,并且在 Application_Start 返回之前不会出现(仍然不确定为什么?)。所以我想我会作弊并将最初的 addserviceroute 调用移动到 service1 的构造函数。也没有工作。

有人提到这不应该在构造函数中——我同意,这只是测试代码。

还提到了一个单例,这可能没问题,但我打算在一台机器上(在同一个应用程序池中)拥有多个 Service1 实例,所以我认为这行不通?

** 更新 #2 ** 我被要求提供示例代码.. 这里来自 global.asax(为简洁起见,稍微修剪了一下).. 所以http://localhost/Test确实出现了.. 但如果我必须使用appfabric 来预热 Test 并让它的构造函数触发,那么我不需要 Test.svc 什么的吗?我如何让 appfabric 甚至看到此服务存在?

protected void Application_Start(object sender, EventArgs e)
        {
            RouteTable.Routes.Ignore("{resource}.axd/{*pathInfo}");
            RouteTable.Routes.Add(
                new ServiceRoute("Test", new MyServiceHostFactory(ITestService, BindingType.BasicHttpBinding, true), TestService)); 
        }
4

2 回答 2

2

我会推荐 AppFabric 自动启动——即使你说你不能使用它——这就是它要解决的问题(预热你的服务)。

作为 AppFabric 存在之前的替代方案,您必须使用计划任务(又名 cron 作业)和调用您要初始化的服务的可执行文件。AppFabric 自动启动的工作方式是使用命名管道 ( net.pipe) 来触发预热- 但它只是在服务回收时执行此操作。计划任务方法和 AppFabric 自动启动之间的区别在于计划任务不知道您的应用程序池何时被回收 - 您需要定期轮询您的服务以使其保持温暖。

或者,您可以考虑通过自托管在 IIS 之外托管您的 WCF 应用程序。这将避免预热问题,但您不会获得 IIS 托管容器的许多好处。HttpSelfHostServer在新的 MVC Web API 中查看或使用标准查看ServiceHost

于 2012-04-09T13:40:47.460 回答
2

您所描述的需要单例服务(您应该避免这样做),因为通常每个调用或会话都会获得一个新实例 = 对构造函数的新调用。在自托管 WCF 服务中,您可以实例化单例服务实例并将其传递给ServiceHost构造函数。如果与您一起使用 IIS 托管服务,ServiceRoute您可以尝试创建自己的派生类ServiceHostFactory,并将创建的服务实例作为参数传递给其构造函数。在这个工厂类中实现CreateServiceHost方法并将现有的服务实例传递给ServiceHost构造函数。要完成这项工作,您的服务类仍必须通过服务行为作为单例处理。

顺便提一句。构造函数不应该做任何耗时的操作。构造函数用于构造对象而不是用于初始化基础设施。首先,使用构造函数进行此类初始化是不好的做法。

于 2012-04-09T09:33:17.060 回答