在S#arp Architecture项目中使用wcf服务

时间:2010-06-24 18:36:54

标签: wcf s#arp-architecture

我有一个敏锐的架构项目,我也在使用ApplicationServices。

需要提供将使用wcf服务的winform客户端。 wcf服务将依次使用ApplicationServices。我还没有开始使用winform客户端,但我正在研究wcf服务。

继Northwind示例之后。我在我的解决方案中创建了一个“Wcf服务库”项目和一个“Wcf服务应用程序”项目。

我是wcf的新手,但我知道所有基础知识并且过去曾经使用过很多Web服务。我有以下问题: -

1)我想知道为什么需要两个项目,wcf库和wcf应用程序?

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

public interface ITerritoriesWcfService : ICloseableAndAbortable

ICloseableAndAbortable的目的是什么?

3)还有另一个类TerritoryWcfServiceClient

public partial class TerritoriesWcfServiceClient : ClientBase<ITerritoriesWcfService>, ITerritoriesWcfService

这门课的目的是什么?

4)在TerritoriesService.svc文件中,Factory =“SharpArch.Wcf.NHibernate.ServiceHostFactory,SharpArch.Wcf”的目的是什么?通常在普通的wcf服务应用程序中,我使用codebehind属性,但由于.cs文件实际上驻留在wcf服务库项目中,我想知道以下代码在做什么?

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

即使我删除了上面的Factory属性,我仍然可以运行服务应用程序项目并使用WcfTestClient实用程序测试服务。

6)当我运行我的服务并使用WcfTestClient时如果我运行两次访问存储库的方法,那么在第二次调用时,我得到一个ObjectDisposedException。

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

我相信NHibernate Session在第一次调用后就会被释放。如何重新启动每个电话或我应该保持开放?我想知道最佳做法吗?

7)此外,如果我运行Northwind.Wcf.Web项目并单击TerritoriesService.svc  在目录列表屏幕上的文件,我收到以下错误

{“方法'生成'类型'Northwind.Data.NHibernateMaps.AutoPersistenceModelGenerator'来自程序集'Northwind.Data,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null'没有实现。”:“ Northwind.Data.NHibernateMaps.AutoPersistenceModelGenerator“}

我不明白为什么它会抛出这个错误,当我已经有了方法并且Northwind.Web工作正常。

等待 纳比尔

1 个答案:

答案 0 :(得分:2)

1)严格来说,您可以组合WCF库和WCF应用程序 在一个集会中。这意味着你要合并合同 和一个程序集中的实现。

如果您使用的是svcutil.exe或Visual Studio(使用svcutil.exe) 反过来)为你的客户生成代理类,你会没事的 因为代理类是从你的发现中生成的 服务。

但是,如果您想使用自己的类进行传输,那就是 在DTO场景等中很常见,你需要引用一个 来自客户端和服务器的共享库。如果那个共享 库将是您的组合库/应用程序集, 客户端将获得范围内的应用程序实现(因为它 引用包含合同的程序集)这是真的 不是你想要的东西。客户需要了解尽可能少 关于服务器的可能性,与合同公开的一样多 - 这就是合同的首要目的。

我认为将接口/合同分开是最佳做法 无论如何实施,因为它导致更好的分离 关注。只是解决方案的大多数部分都不需要(和 不应该知道有什么事情已经完成,只是知道什么事情可以做到 做。与此相比,还有许多其他优点,例如改进 可测试性。

2)取自ICloseableAndAbortable的代码文档:

“当您的WCF合同实施时,它们可以互换 使用WCF客户端代理。这使得使用依赖更简单 注入并模拟WCF服务而不必担心 如果你关闭/中止它是一个WCF客户端。“。

我认为这就是全部。

3)客户端类与代码文档一样强烈 键入的客户端代理。客户端可以使用它与服务器通信, 提供一个强类型类,其成员对应于 可以在服务器上调用的服务操作。

这个类的优点是你不需要使用 svcutil.exe生成的代理类。这就是他们没有的意思 通过WCF配置配置它。这允许您运送代理 为您的客户提供课程,以便他们可以立即与您的服务器通信 而不是先生成代理类。它允许更多的控制 同样,更改代理类生成的代码是 真的不是你想要做的事情。

这也是将接口/契约放入的一个很好的理由 因为您不想发送服务而单独组装 实施代码给您的客户。

4)服务主机工厂基于创建服务实例 提供服务类型。如果你想放入,这可以派上用场 服务代码,而不是代码隐藏文件。你也是 如果您使用Depency Injection需要它,您需要提供服务 合同接口作为类型和SharpArch.Wcf服务主机 工厂通过手段将其解析为正确的实现类类型 DI框架(SA温莎城堡)。你可以把它想象成一个 在不关心的情况下掌握服务实施的方法 关于它实际来自哪里。

在这种情况下,服务将在您删除工厂时运行 属性,因为默认工厂能够解析服务 类型。你绕过像DI和会话管理这样的东西, 究竟是什么让SA值得。

5)我将不得不跳过这一个,因为显然没有问题5: - )

6)与Northwind示例项目一样,您可能正在使用SA附带的ServiceHostFactory。使用此服务主机工厂,每个创建的服务实例都会通过在调用后直接关闭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)对不起,我真的不知道。我稍后可能会对此进行研究。