lysergic-acid
lysergic-acid

Reputation: 20050

Proper design for a WCF service that accesses data

I am designing a WCF service that accesses some data stored in a database.

The actual access to the DB is handled by some ORM layer (currently NHibernate, but this is an implementation detail).

I am wondering what is the proper design for this sort of scenario?

The naive approach would be something like:

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

     // service methods that use *session*
}

This is coupled specifically to NHibernate and forces the service class to manage initialization and owning the ORM logic code.

My questions are in particular:

Since this is such a common scenario, i assume some "patterns" / best practices exist.

Most examples that are available online, demonstrate HOW to achieve this (how to use an ORM to access a DB, etc) but not how this should be properly done from a design perspective, on a larger scale.

Upvotes: 2

Views: 112

Answers (1)

Steve Westbrook
Steve Westbrook

Reputation: 1708

Assuming you want to initialize only once, you might want to consider setting up your service implementation class with the following attribute:

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

This will cause your service to hold a single instance in memory, with multiple callers all accessing that instance. The downside is that your code will have to be thread-safe; additionally, you won't be able to call through to a second WCF service (for this, you need Reentrant concurrency).

However, in this scenario, you can hold a class instance in your service which controls the DB/ORM side of things, achieving the decoupling you desire.

Initialization of the DB/ORM can be carried out in the service's constructor.

Note that it is not wise to make use of a static member variable containing DB/ORM functionality. This is because even static values may be reclaimed by the service host given a sufficient period of inactivity.

This is of course only one way to achieve what you want: you might benefit from examining the cost of multiple initialization vs. the P.I.A. of writing thread-safe code. A compromise would be to use InstanceContextMode.PerSession - a single user session would then have the ORM initialized only once, cutting down on initializations if a user is likely to make multiple calls. The overhead of defining and controlling sessions is a minor irritant at best, and one which, given how long I've rambled on already, is outside the scope of this response.

Upvotes: 1

Related Questions