2013-03-07 56 views
2

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

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

我想知道什么是这种情况下适当的设计?

天真的做法是这样的:

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

    // service methods that use *session* 
} 

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

我的问题是特别:

  • 我如何实现解耦设计,其中业务从DB/ORM层分离?
  • 应该初始化数据库访问/ ORM层?服务是否管理?

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

大多数可在线获得的示例演示了如何实现这一点(如何使用ORM访问数据库等),而不是从设计的角度来看,如何在更大范围内正确地完成这些操作。

回答

1

假设你希望只初始化一次,你可能要考虑建立你的服务实现类具有以下属性:

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

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

但是,在这种情况下,您可以在您的服务中持有一个控制事物的DB/ORM端的类实例,实现您希望的解耦。

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

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

这当然只有一种方法可以实现你想要的:你可以从检查多重初始化与P.I.A的成本中受益。编写线程安全代码。一个折中的办法是使用InstanceContextMode.PerSession - 一个用户会话然后只会初始化ORM一次,如果用户可能进行多次调用,则会减少初始化次数。定义和控制会话的开销最多只是一个小小的刺激,而且在我已经漫游了多久的情况下,这个超出了这个响应的范围。

+0

我已经将ContextMode设置为单个(不确定它是否是最理想的选择)。在我的服务中保持NHibernate的类实例如何实现分离设计? – 2013-03-07 18:08:21

+0

如果您创建了一个类并将所有ORM初始化代码放入其中,并根据需要进行查询,则会实现解耦。 – 2013-03-07 18:15:10