正确设计访问数据的WCF服务

时间:2013-03-07 17:24:32

标签: c# database wcf wcf-data-services

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

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

我想知道这种情况的正确设计是什么?

天真的做法是:

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

     // service methods that use *session*
}

这与NHibernate特别相关,并强制服务类管理初始化并拥有ORM逻辑代码。

我的问题特别是:

  • 如何在服务与DB / ORM层分离的情况下实现解耦设计?
  • 何时应该初始化db access / ORM层?服务管理那个吗?

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

大多数可在线获得的示例,演示了如何实现这一目标(如何使用ORM访问数据库等),而不是如何从设计角度更大规模地完成此操作。

1 个答案:

答案 0 :(得分:1)

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

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

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

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

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

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

这当然只是实现您想要的一种方式:您可以从检查多次初始化的成本与P.I.A中获益。编写线程安全代码。折衷方案是使用InstanceContextMode.PerSession - 单个用户会话将使ORM仅初始化一次,如果用户可能进行多次调用,则会减少初始化。定义和控制会话的开销最多只是一个小小的刺激因素,而且考虑到我已经漫游的时间已经超出了这个响应的范围。