【问题标题】:Proper design for a WCF service that accesses data访问数据的 WCF 服务的正确设计
【发布时间】:2013-03-07 17:24:32
【问题描述】:

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

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

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

天真的方法是这样的:

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

     // service methods that use *session*
}

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

我的问题特别是:

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

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

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

【问题讨论】:

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


    【解决方案1】:

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

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

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

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

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

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

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

    【讨论】:

    • 我已经将 ContextMode 设置为 single(不确定是否是最理想的选择)。在我的服务上保留 NHibernate 的类实例如何实现解耦设计?
    • 如果你创建一个类,把所有的ORM初始化代码放进去,按需查询,就可以实现解耦了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多