2010-06-24 74 views
1

我有一個尖銳的體系結構項目,我也在其中使用ApplicationServices。在S#arp中使用wcf服務體系結構項目

需要提供一個使用wcf服務的winform客戶端。 wcf服務將依次使用ApplicationServices。我還沒有開始使用winform客戶端,但我正在開發wcf服務。

繼Northwind示例。我在我的解決方案中創建了「Wcf服務庫」項目和「Wcf服務應用程序」項目。

我是wcf的新手,但是我知道所有的基礎知識,並且在過去一直使用web服務。我有以下問題: -

1)我想知道爲什麼需要兩個項目,wcf庫和wcf應用程序?

2)我注意到Northwind示例中的ITerritoriesWcfService接口繼承ICloseableAndAbortable。

public interface ITerritoriesWcfService : ICloseableAndAbortable 

ICloseableAndAbortable的用途是什麼?

3)還有一種類TerritoriesWcfServiceClient

public partial class TerritoriesWcfServiceClient : ClientBase<ITerritoriesWcfService>, ITerritoriesWcfService 

這是什麼類的目的是什麼?

4)在TerritoriesService.svc文件中,Factory =「SharpArch.Wcf.NHibernate.ServiceHostFactory,SharpArch.Wcf」的目的是什麼?通常在一個正常的WCF服務應用程序,我使用的代碼隱藏屬性,但由於實際的.cs文件所在的int WCF服務庫項目,我想知道,下面的代碼是什麼做的?

<%@ ServiceHost Language="C#" Debug="true" 
    Service="Northwind.Wcf.TerritoriesWcfService" 
    Factory="SharpArch.Wcf.NHibernate.ServiceHostFactory, SharpArch.Wcf" %> 

即使刪除了上述工廠屬性,我仍然可以運行服務應用項目,並利用WcfTestClient實用測試服務。

6)當我運行我的服務,並使用WcfTestClient如果我運行一個方法兩次訪問的存儲庫,然後在第二個電話,我得到一個的ObjectDisposedException。

{"Session is closed!\r\nObject name: 'ISession'."} 

我相信NHibernate Session會在第一次調用之後被拋棄。如何爲每次通話重新初始化,還是應該保持開放狀態?我想知道最佳做法?

7)另外,如果我運行Northwind.Wcf.Web項目,並單擊TerritoriesService.svc 文件目錄列表屏幕上,我得到以下錯誤

{「方法類型'生成「羅斯文.Data.NHibernateMaps.AutoPersistenceModelGenerator'from Northwind.Data,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null'沒有實現。「:」Northwind.Data.NHibernateMaps.AutoPersistenceModelGenerator「}

我不明白爲什麼它拋出這個錯誤,當我已經有了方法和Northwind.Web正常工作了。

等待 納比爾

回答

2

1)嚴格,你可以結合WCF圖書館和一個組裝WCF應用程序 。這意味着您將合併 和一個程序集中的實現。

如果使用svcutil.exe的或Visual Studio(又使用svcutil.exe的 )生成代理類爲您的客戶,你會被罰款 因爲代理類是從你 服務的發現產生。

但是,如果您想使用自己的傳輸類,即在DTO場景等中很常見的 ,則需要從客戶端和服務器引用 共享庫。如果共享的 庫是您的組合庫/應用程序集合,那麼 客戶端將獲得應用程序實現(因爲它引用包含合同的程序集),而這實際上不是您想要的東西 。客戶需要儘可能少地瞭解服務器,就像合同公開的那樣 - 這就是合同首先要做的。

我認爲最好的做法是將界面/合同從 分開實施,因爲它可以更好地分離 的問題。這只是因爲你的解決方案的大部分內容都不需要(並且不應該)知道如何完成某些事情,只要 可以做什麼。除此之外還有更多的優點,例如改進的可測試性 。從IClo​​seableAndAbortable的代碼資料爲準

2):

「當你的WCF的合同執行,他們再互換 與WCF客戶端代理這使得它更容易使用的依賴 注入和嘲笑WCF服務,無需擔心 如果它是一個WCF客戶端,當你關閉/中止它時。「。

我覺得這一切都說了。

3)與代碼文檔中所述的一樣,客戶端類是強烈的 類型的客戶端代理。它可以被客戶端用來與服務器交談, 提供一個強類型的類,其成員對應於可以在服務器上調用的服務操作。

這個類的優點是你不需要使用svcutil.exe生成的代理類 。這就是他們沒有 通過WCF配置來配置它的意思。這允許您將代理 課程發送給您的客戶,以便他們可以立即與您的服務器 對話,而不是先生成代理類。它允許更多的控制 以及更改由代理類生成的代碼是 真的不是你想要做的事情。

由於您不想將服務 實施代碼發送給您的客戶,因此再次將接口/合同放在單獨的組件中是一個很好的理由。

4)服務主機工廠根據提供的服務類型創建服務實例。如果您想將 服務代碼放在除了文件後面的代碼之外的某處,這可以派上用場。如果您使用Depency Injection,您還需要 ,您將提供服務 合同接口作爲類型,並且SharpArch.Wcf服務主機 工廠通過DI框架的方式將其解析爲正確的實施類類型 (南卡羅來納州溫莎城堡)。您可以將此視爲 獲取服務實現的方式,而不關心 實際來自哪裏。

在這種情況下,服務將在您移除工廠 屬性時運行,因爲默認工廠能夠解析服務 類型。你正在繞過像DI和會話管理這樣的東西,儘管這正是SA價值所在。

5)我會因爲很顯然有,你可能正在使用附帶的SA沒有ServiceHostFactory問題編號5 :-)

6)在羅斯文示例項目跳過這一項。通過這個服務主機工廠,每個創建的服務實例都會被一個行爲擴展,該行爲在調用之後直接關閉NHibernate會話。這本身就沒問題,但很有可能你的代理客戶不是由Castle Windsor以短暫的方式管理的。因此實例被重用,包括它們(仍然)包含的閉合會話。使用Transient屬性(Castle.Core.TransientAttribute)裝飾您的客戶端代理類,Castle Windsor將在每次執行服務調用時創建一個新實例。

顯然,還有第二種解決方法,但它需要修改S#arpArchitecture代碼庫。請參閱GitHub上的WCF connections which process more than one request fail because the nhibernate session is closed and isn't re-opened.。 7)對不起,我真不知道。我可能會在稍後看看。

+0

http://groups.google.com/group/sharp-architecture/browse_thread/thread/1f2d8910d2b22763?hl=zh_CN – nabeelfarid 2010-07-12 08:32:25