2

我正在设计一个访问存储在数据库中的一些数据的 WCF 服务。

对数据库的实际访问由一些 ORM 层处理(目前是NHibernate,但这是一个实现细节)。

我想知道这种场景的正确设计是什么?

天真的方法是这样的:

public class ServiceImplementation : IService
{
     // NHibernate session
     private ISession session;

     // service methods that use *session*
}

这专门与 NHibernate 耦合,并强制服务类管理初始化并拥有 ORM 逻辑代码。

我的问题特别是:

  • 如何实现服务与 DB/ORM 层解耦的解耦设计?
  • 何时以及由谁初始化数据库访问/ORM 层?服务管理吗?

由于这是一种常见的情况,我假设存在一些“模式”/最佳实践。

在线提供的大多数示例都演示了如何实现这一点(如何使用 ORM 访问数据库等),但没有从设计的角度在更大范围内正确地完成这一点。

4

1 回答 1

1

假设您只想初始化一次,您可能需要考虑使用以下属性设置服务实现类:

[ServiceBehavior(InstanceContextMode=InstanceContextMode.Single, ConcurrencyMode=ConcurrencyMode.Multiple)]

这将导致您的服务在内存中保存一个实例,多个调用者都访问该实例。缺点是你的代码必须是线程安全的。此外,您将无法调用第二个 WCF 服务(为此,您需要可重入并发)。

但是,在这种情况下,您可以在您的服务中保存一个类实例来控制事物的 DB/ORM 方面,从而实现您想要的解耦。

DB/ORM 的初始化可以在服务的构造函数中进行。

请注意,使用包含 DB/ORM 功能的静态成员变量是不明智的。这是因为即使是静态值也可能被服务主机在足够长的不活动期间回收。

这当然只是实现您想要的一种方法:您可能会从检查多次初始化的成本与编写线程安全代码的 PIA 中受益。一个折衷方案是使用 InstanceContextMode.PerSession - 单个用户会话将只初始化一次 ORM,如果用户可能进行多次调用,则减少初始化。定义和控制会话的开销充其量只是一个小刺激,考虑到我已经讨论了多长时间,这超出了本回复的范围。

于 2013-03-07T18:01:32.323 回答