.Net - Separation of a job template for multiple ORMs

My current application structure:

  • Assembly simulation
  • Data collection
    • Defines repository interfaces to be implemented using ORM
  • ORM assembly
    • Implements repository interfaces from data assembly
    • Uses a unit (IoC container) to register Data.IRepository<> to ORM.GenericRepository<>
  • Business assembly
    • Links to data and model assembly
    • Uses Unity to IRepository<> Types
  • user interface assembly
    • Business assembly links

This structure significantly disconnected the business layer from ORM, which implements IRepository<T> .

One of the advantages of this decoupled structure is that I should be able to easily replace ORMs - for example, go from Entity Framework to NHibernate or just upgrade an existing ORM. I am currently using EF 4.1 code and am creating another build for NHibernate.

I am considering using the Unit of Work template.

I read that this template should be used at the business level (with the interfaces defined in my data assembly, and implemented in the ORM assembly in the same way as with the repository template). Currently, all created instances of the repository have their own DbContext / session, and its lifetime is set to the repository repository - which can be bad. My problem is that I'm not sure that it is possible to implement a Unit of Work template that will work with different ORMs (most likely, it probably is, and I'm just not up to speed).

This is the only thing that comes to mind:

Create IUnitOfWork in my data assembly, which has a function: object GetCurrentSession(); , then specify the argument in the repository designer in the ORM assembly and pass it to the corresponding / DbContext session (if NHibernate then ISession, if Entity Framework then DbContext)

I would appreciate if someone had some idea of ​​this situation.

+4
source share
1 answer

Perhaps I found a solution (have not tried it yet):

In data assembly:

 public interface IUnitOfWork : IDisposable { void Start(); T Current<T>(); // IDisposable stuff } 

In the ORM assembly:

 public class GenericRepository<T> : IRepository<T> where T : PersistentEntity { private ISession CurrentSession; public GenericRepository(IUnitOfWork uow) { CurrentSession = uow.Current<ISession>(); } // other repository stuff here } public class NHhibernateUnitOfWork : IUnitOfWork { private ISession CurrentSession; public void Start() { // instantiate CurrentSession } T Current<T>() { if(typeof(T) is ISession) return (T)CurrentSession; else return new NotImplementedException(); } } // in the prism module container.Resolve(typeof(IUnitOfWork), typeof(NHhibernateUnitOfWork)); 

In the Build Business:

 IUnitOfWork uow = container.Resolve<IUnitOfWork>(); using(uow.Start()) { IRepository custRepo = container.Resolve<IRepository<Customer>>(uow); // do stuff here with cust repo } 

This is just proof of the concept of decoupling IUnitOfWork from a specific implementation.

0
source

Source: https://habr.com/ru/post/1347328/


All Articles