我正在设计一个WCF服务来访问存储在数据库中的一些数据。
对DB的实际访问由一些ORM层处理(当前 NHibernate ,但这是一个实现细节)。
我想知道这种情况的正确设计是什么?
天真的做法是:
public class ServiceImplementation : IService
{
// NHibernate session
private ISession session;
// service methods that use *session*
}
这与NHibernate特别相关,并强制服务类管理初始化并拥有ORM逻辑代码。
我的问题特别是:
由于这是一种常见的情况,我假设存在一些“模式”/最佳实践。
大多数可在线获得的示例,演示了如何实现这一目标(如何使用ORM访问数据库等),而不是如何从设计角度更大规模地完成此操作。
答案 0 :(得分:1)
假设您只想初始化一次,您可能需要考虑使用以下属性设置服务实现类:
[ServiceBehavior(InstanceContextMode=InstanceContextMode.Single, ConcurrencyMode=ConcurrencyMode.Multiple)]
这将导致您的服务在内存中保存单个实例,多个调用者都访问该实例。缺点是你的代码必须是线程安全的;此外,您将无法调用第二个WCF服务(为此,您需要重入并发)。
但是,在这种情况下,您可以在服务中保存一个控制DB / ORM方面的类实例,实现您想要的解耦。
DB / ORM的初始化可以在服务的构造函数中执行。
请注意,使用包含DB / ORM功能的静态成员变量是不明智的。这是因为即使是静态值,服务主机也可以在给定足够的不活动时间的情况下回收它。
这当然只是实现您想要的一种方式:您可以从检查多次初始化的成本与P.I.A中获益。编写线程安全代码。折衷方案是使用InstanceContextMode.PerSession - 单个用户会话将使ORM仅初始化一次,如果用户可能进行多次调用,则会减少初始化。定义和控制会话的开销最多只是一个小小的刺激因素,而且考虑到我已经漫游的时间已经超出了这个响应的范围。