2010-06-24 39 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