我有一个简单的应用程序,我使用global.asax通过Application_Start中的自定义servicehostfactory将serviceroute映射到wcf服务。该服务的构造函数进行一些初始处理以设置服务,这需要一些时间。
我需要在自动添加serviceroute时触发此构造函数。我尝试从global.asax创建一个clientchannel并进行虚拟调用以启动服务,但发现服务还没有启动 - 似乎application_start必须返回?
那么如何在首次通过global.asax映射而不必手动命中服务时获取服务的构造函数?不幸的是AppFabric不是我们的选择,所以我不能只使用它的内置自动启动..
更新
我被要求提供更多细节;
这就像路由管理服务。所以我有Service1 - 它被添加为global.asax中的serviceroute。现在我有http://localhost/Service1
Inside 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));
}
答案 0 :(得分:2)
您所描述的内容需要单件服务(您应该避免的事情),因为通常每个调用或会话都会获得一个新实例=对构造函数的新调用。在自托管WCF服务中,您可以实例化单例服务实例并将其传递给ServiceHost
构造函数。如果IIS托管服务与ServiceRoute
一起使用,您可以尝试创建自己的派生自ServiceHostFactory
的类,并将创建的服务实例作为参数传递给其构造函数。在此工厂类中实现CreateServiceHost
方法,并将该现有服务实例传递给ServiceHost
构造函数。要完成此项工作,您的服务类仍必须作为singleton through service behavior处理。
顺便说一下。构造函数不应该做任何耗时的操作。构造函数用于构造对象而不是用于初始化基础结构。首先使用构造函数进行初始化是不好的做法。
答案 1 :(得分:2)
AppFabric自动启动是我推荐的 - 即使你说你不能使用它 - 这是它要解决的问题(加热你的服务)。
作为AppFabric存在之前的替代方案,您必须使用一个可执行的任务( a.k.a cron job ),该任务调用您想要初始化的服务。 AppFabric自动启动的工作方式是using named pipes (net.pipe
) to trigger the warm up - 但它只是在服务被回收时才会这样做。计划任务方法与AppFabric自动启动之间的区别在于计划任务不知道您的应用程序池何时被回收 - 您需要定期轮询您的服务以使其保持温暖。
或者,您可以考虑通过自托管在IIS之外托管您的WCF应用程序。这样可以避免热身问题,但是您无法实现IIS托管容器的许多好处。请参阅HttpSelfHostServer
in the new MVC Web API或review using a standard ServiceHost
。