访问数据的WCF服务的适当设计

本文关键字:服务 数据 WCF 访问 | 更新日期: 2023-09-27 18:03:02

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

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

我想知道这种场景的适当设计是什么?

朴素的方法是这样的:

public class ServiceImplementation : IService
{
     // NHibernate session
     private ISession session;
     // service methods that use *session*
}

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

我的问题是特别的:

  • 如何实现服务从DB/ORM层解耦的解耦设计?
  • 何时应该初始化数据库访问/ORM层?该服务能够管理这些吗?

由于这是一个常见的场景,我假设存在一些"模式"/最佳实践。

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

访问数据的WCF服务的适当设计

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

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

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

然而,在这种情况下,你可以在你的服务中保持一个类实例,它控制DB/ORM方面的事情,实现你想要的解耦。

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

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

这当然只是实现目标的一种方法:您可能会从检查多次初始化的成本与编写线程安全代码的P.I.A.中受益。折衷的方法是使用InstanceContextMode。session—单个用户会话将只初始化ORM一次,如果用户可能进行多次调用,则减少初始化。定义和控制会话的开销充其量只是一个小问题,考虑到我已经漫谈了这么长时间,它已经超出了这个响应的范围。