[英]WCF call that references Windows Service
我有一項長期服務,可以從一個來源獲取數據,對其進行處理,然后將其存儲在數據庫中,等等。
我想向其他應用程序公開該服務的某些方法。 目前,我們是通過.NET Remoting完成此操作的,但我想轉到WCF。
不幸的是,我所連接的端點永遠不會是我通過長期運行的服務所暴露的端點。 下面是一個簡單的示例:
[ServiceContract]
public interface ITestWcfService
{
[OperationContract]
CounterResult GetCurrentValue();
}
public class TestWcfService : ITestWcfService
{
private ITestWindowsService _service;
public TestWcfService() { /*NOTE: For discoverability*/ }
public TestWcfService(ITestWindowsService service)
{
_service = service;
}
public CounterResult GetCurrentValue()
{
return _service.GetCurrentValue();
}
}
public interface ITestWindowsService
{
CounterResult GetCurrentValue();
}
然后,我得到了實際的Windows服務,該服務通過ServiceHost類自托管WCF服務。
public partial class TestWindowsService : ServiceBase, ITestWindowsService
{
private static ServiceHost _wcfService;
public TestWindowsService()
{
InitializeComponent();
}
public void OnStart(string[] args)
{
//Create instance of WCF, passing in reference to this service instance
TestWcfService wcf = new TestWcfService(this);
_wcfService = new ServiceHost(wcf);
}
public CounterResult GetCurrentValue()
{
//Note: Some logic here
}
}
現在,這種或多或少的工作原理是,每次我調用TestWcfServiceClient()
,它將使用默認構造函數並創建Wcf服務的新實例,而不使用Windows服務創建的實例。 這意味着,當我調用GetCurrentValue()
由於未設置_service
成員,因此會得到空引用。
我到處尋找解決方案,並找到了一些引用ServiceHostFactory
, ServiceHost
和IInstanceProvider
但它們似乎都非常非常復雜。
您提供的任何想法將不勝感激。
編輯 :這是我的ServiceModel信息
<system.serviceModel>
<services>
<service name="WcfService.TestWcfService">
<host>
<baseAddresses>
<add baseAddress = "http://localhost:8733/Design_Time_Addresses/WcfService/TestWcfService/" />
</baseAddresses>
</host>
<!-- Service Endpoints -->
<!-- Unless fully qualified, address is relative to base address supplied above -->
<endpoint address="" binding="basicHttpBinding" contract="WcfService.ITestWcfService">
<!--
Upon deployment, the following identity element should be removed or replaced to reflect the
identity under which the deployed service runs. If removed, WCF will infer an appropriate identity
automatically.
-->
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<!-- Metadata Endpoints -->
<!-- The Metadata Exchange endpoint is used by the service to describe itself to clients. -->
<!-- This endpoint does not use a secure binding and should be secured or removed before deployment -->
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata information,
set the values below to false before deployment -->
<serviceMetadata httpGetEnabled="True" httpsGetEnabled="True"/>
<!-- To receive exception details in faults for debugging purposes,
set the value below to true. Set to false before deployment
to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="False" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
WCF是非常可擴展的,但是要提供這種可擴展性,它也非常復雜。 我認為,如果要使用此實現,那就不應該了。 您必須創建一種更改服務工廠的行為,以便您可以使用自定義構造函數而不是空的構造函數。
但是,我認為可能還有另一種選擇。 由於服務和WCF共享同一個應用程序域,因此它們可以通過靜態對象共享值。
我將移動承載要公開給底層程序集(如果尚未公開)的值的邏輯,並且服務和WCF服務將看到相同的實例,因此您無需更改所有WCF管道。
您試圖將一個方形的釘子放在一個圓孔中。
WCF被明確設計為能夠獨立於其托管方式來調用業務邏輯。 您正在嘗試維護在主機層(在本例中為Window的服務)中具有業務邏輯的舊的遠程設計。 結果,您要求以一種在WCF中可能但又難看的方式將信息傳遞回主機,這通常由於許多良好的原因而被避免。
如果您想要干凈的WCF設計,則需要創建抽象層並將業務邏輯移出現有的TestWindowsService類。 然后,Windows服務創建WCF服務主機,WCF主機創建WCF服務,並且WCF服務不依賴於承載它的類。
說了這么多...
實際回答您的問題:
從概念上講,您編寫的代碼應該可以使用。 到目前為止,將對象實例傳遞到ServiceHost構造函數是避免編寫自定義IInstanceProvider的復雜性的最簡單方法。 需要檢查的幾件事:
將服務實例傳遞到ServiceHost構造函數時,需要將其標記為單例 。
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
確保初始化確實按照您認為的方式工作:
如果仍然有問題:app.config的“服務模型”部分是什么樣的?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.