Data Access across modules

Topics: Prism v4 - WPF 4
Oct 24, 2011 at 1:47 PM

I'm new to building composite applications and Prism and would like some input on how to deal with data access.

The Prism reference implementation has data (xml files) defined in each module. In my case I would like to share the data access across modules. I suppose in a modular application only the module know what specific entities and repositories are to be specified. Also only the data access layer will know how to persistence the data and I suppose it would be not clever to duplicate this logic over several modules.

Today I have a generic repository / interface in the DAL.

Should this be a own Prism module, or a dll reference in each module who needs data access? I suppose the latter is easier, but not as loosely coupled?

Any hint on how to approach?

Developer
Oct 24, 2011 at 7:16 PM

Hi,

In my opinion, a good approach to fulfill this requirement would be to define the interface for your service in an infrastructure project (probably, if your service retrieves and saves instances of a specific model, you would have to put that model class in the infrastructure project as well); and then, define an implementation of that service on a certain module, and export it to the container using the aforementioned interface as the contract type.

This way, since infrastructure projects are usually referenced throughout all your other projects in the application, every component will be able to consume your service, but without knowing its concrete implementation. This is known as shared services, and you can read more about it in the following section from the Communication chapter in the Prism MSDN documentation:

You might also find the following blog post useful, where an example of this scenario can be seen. In this case, the data access layer is a mock service that returns mock values, but the idea is similar to what I mentioned above:

Using WCF services in Prism Silverlight applications

I hope you find this helpful.

Guido Leandro Maliandi 
http://blogs.southworks.net/gmaliandi


Oct 25, 2011 at 7:50 AM

Thank you for your detailed answer Guido! Your approach seems reasonable - I will look into your links and hopefully get a grasp on this :)

Nov 17, 2011 at 8:15 AM
Edited Nov 17, 2011 at 8:58 AM

A little follow up question on this one

So I got my modules set up (Unity) and a data module that will do my persistence. That is done with nHibernate. Using nHibernate I have a IRepository<T> and a Repository<T> that will do my most basic CRUD operations and also from which specialized repositories can inherit in different modules.

Ideally I'd like my data module to be independent on the ORM (say in 5 years everyone is all excited about some new technology/ORM). I find this hard as a repository takes in an ISession (nHibernate interface) to work on.

What I'd like to do is (and very open to other suggestions)

-- Infrastructure
 |- IRepository<T> where T : IEntity
 |- IEntity
 |- Customer : IEntity

-- Modules.Data
|- Repository<T>(ISession session) (register as a service in module Initialize)
|- SessionFactory (as a service) (singleton with OpenSession() method)

-- Modules.Customer
|- CustomerRepository<Customer>(ISession session) : Repository<T>(session)

Reading this article of best practices using nHibernate with Windows application it encourages to have a session-per-form scenario. Then I have a dependecy on my session object type (ISession) throughout my application. Unplugging my data module and inserting a new one will not work as I will have to sort out all the places ISession were used.

Also I found registering generic services (Repository<T>) hard as I would like my module to define that T. A way around is to move the <T> to the method implementations instead (GetById<T> where T : IEntity)

But my biggest problem is that how to inherit from my base repository from my modules. Does it makes sense to move it to Infrastructure? Then only my SessionFactory will be left in my Data module with some conventions.

So to sum it up - I (think I) understand the concept of sharing services and so on in Prism, but how to do it in a generic way and without getting a dependency on my ORM implementation? Adding a business layer module that will hold all the session implementation? As such I will only have to change two modules in the future.

Any thoughts on this is appreciated :)

Developer
Nov 17, 2011 at 2:46 PM

Hi,

Based on my understanding you could apply a structural pattern such as the Adapter or Façade patterns, to obtain abstraction over the NHibernate interface.

You can find more information about these patterns in the following links:

I hope you find this helpful

Agustin Adami
http://blogs.southworks.net/aadami