2011-04-20 129 views
0

我用一个简单的'hello world'测试服务和一个正确配置的App.config文件创建了一个WCF服务库,以便当我启动我的客户端应用程序时,WCF服务通过Visual Studio的内置主机启动。目前的服务与我客户端的外部配置工作正常。如何在不是自托管的WCF服务库中执行初始化?

我需要运行一些初始化代码来设置DI,数据访问,日志记录等。我编写了一个控制台主机,可以做到这一点,并且服务本身最终将作为Windows服务部署,但我想使用内置主机,这样我就不必在开发过程中手动重新启动服务。

有没有什么办法可以在启动时调用库中的一些代码?

+0

你能澄清一下:“有没有什么办法可以挂钩库中的一些代码以便在启动时调用?”,因为这听起来完全不相关“我想使用内置主机,所以我没有在开发过程中手动重启服务。“ – 2011-04-20 01:57:43

回答

3

我发现了另一个关于使用custom ServiceHostFactory to perform bootstrapping的问题,它是通过*.svc文件设置的。 *.svc文件是WCF服务应用程序的一部分,不能直接由WCF服务使用。我想坚持使用服务库来实现一些灵活性,以实现服务和最终的生产托管,但使用WCF服务应用程序将以适合开发的方式完成工作(并且可能很容易丢弃使用另一组配置进入IIS进行生产托管)。所以我想,我只需要创建一个WCF服务应用程序,它充当服务库中服务的主机,并执行所需的初始化。

我首先创建了一个新的WCF服务应用程序,删除了由VS创建的默认服务文件,并添加了对现有服务库和其他依赖项的引用。

在服务应用程序的Web.Config文件,在<configSections>..</configSections>部(其被要求是<configuration>标签后的第一节点),I增加了对服务库中的<system.serviceModel>部分(这可以从App.config文件中的被提取服务库和编辑适合)。

例如:

<system.serviceModel> 
    <services> 
    <service behaviorConfiguration="MyServiceBehavior" name="BelfryImages.QueryService.Implementation.HelloWorld"> 
     <endpoint address="HelloWorld" binding="wsHttpBinding" name="HelloWorld" contract="BelfryImages.QueryService.Contracts.IHelloWorld" /> 
    </service> 
    </services> 

    <behaviors> 
    <serviceBehaviors> 
     <behavior name="MyServiceBehavior"> 
     <serviceMetadata httpGetEnabled="true" /> 
     <serviceDebug includeExceptionDetailInFaults="true" /> 
     </behavior> 
    </serviceBehaviors> 
    </behaviors> 

    <bindings> 
    </bindings> 
</system.serviceModel> 

注意,是服务实现(实现类)的服务合同(接口)BelfryImages.QueryService.Contracts.IHelloWorld的FQN。我实际上有两个独立的程序集, BelfryImages.QueryService.Contracts.dll是WCF服务库。

我向服务应用程序添加了一个新的空白.svc文件,该文件命名为匹配端点,例如HelloWorld.svc。通常,将WCF服务添加到WCF服务应用程序中将生成一个.svc文件和一个.cs代码隐藏文件,其中包含该服务的实现。我没有代码隐藏手动添加的只是.svc文件,并指出,该服务库的实现:

<%@ ServiceHost Language="C#" Debug="true" Service="BelfryImages.QueryService.Implementation.HelloWorld" %> 

原样,这是可以作为一个下拉更换为VS-托管服务库,之后先改变客户的服务网址从http://localhost:XXXXX/QueryService/HelloWorldhttp://localhost:XXXXX/HelloWorld.svc/HelloWorld

然后我创建了ServiceHostFactory来执行服务的初始化。我发现了一个MSDN文章(Hosting and Consuming WCF Services)解释how to do this(清单5-6和5-7) - 我的目的,我只是增加了一个简单,通用CustomHostFactory类:

public class CustomHostFactory 
    : ServiceHostFactory 
{ 
    protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses) 
    { 
     // perform initialisation: 
     ... 

     var serviceHost = base.CreateServiceHost(serviceType, baseAddresses); 
     return serviceHost; 
    } 
} 

这是然后绑定到服务该.svc文件通过添加Factory属性内:

<%@ ServiceHost Language="C#" Debug="true" Service="BelfryImages.QueryService.Implementation.HelloWorld" Factory="BelfryImages.WcfService.CustomHostFactory" %> 

CreateServiceHost()覆盖顶部的初始化照常被创建的服务之前执行。这似乎只发生在每个服务一次,而不是每次调用服务一次,但会有多个服务的开销。这大概可以通过使用静态标志或类似的标志来实现一次性。目前它似乎工作正常。

0

它会在实现您的服务的类的静态构造函数中有初始化代码吗?

public class WCFService : IWCFService 
{ 
    static WCFService() 
    { 
     // do initializing here 
    } 

} 

该代码将在第一次调用服务时执行。

+0

这可以工作,除了当库被部署在另一个主机中时我无法停止运行静态构造函数。 – 2011-04-20 02:12:00