2011-04-20 33 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