S
S
SMARTi2015-08-09 14:47:40
.NET
SMARTi, 2015-08-09 14:47:40

Are the UnitOfWork and Repository patterns for Nhibernate implemented correctly?

I studied the use of NHibernate and patterns and eventually came to this code, this is a test draft, I want to use this in one solution in which there will be two projects, one in the form of services, the other in the form of ASP.NET MVC. I am asking a question in order to understand whether I understood these patterns correctly, whether I used them correctly and whether they are superfluous at all and it was possible not to complicate everything?
Source code (as a single file, requires the System.Data.SQLite, NHibernate, NHibernate.Mapping.Attributes packages to run):

spoiler
using System;
using NHibernate;
using NHibernate.Cfg;
using NHibernate.Mapping.Attributes;
using NHibernate.Tool.hbm2ddl;

namespace NhSQLiteTest
{
    [Class]
    [Serializable]
    public class Product
    {
        [Id(0, Name = "Id", Column = "Id", TypeType = typeof (int))]
        [Generator(0, Class = "identity")]
        public virtual int Id { get; set; }

        [Property]
        public virtual string Name { get; set; }
    }

    internal class Program
    {
        private static void Main()
        {
            using (var uow = new UnitOfWorkFactory().Create())
            {
                var productRepo = new Repository<Product>(uow);
                productRepo.SaveOrUpdate(new Product {Name = "TestRepo"});
            }
            Console.WriteLine("Success!");
            Console.ReadLine();
        }
    }

    public interface IUnitOfWorkFactory
    {
        IUnitOfWork Create();
    }

    public class UnitOfWorkFactory : IUnitOfWorkFactory
    {
        private ISessionFactory _sessionFactory;

        public ISessionFactory SessionFactory
        {
            get
            {
                if (_sessionFactory == null)
                {
                    BuildSessionFactory();
                }
                return _sessionFactory;
            }
        }

        public IUnitOfWork Create()
        {
            return new UnitOfWork(SessionFactory.OpenSession());
        }

        private void BuildSessionFactory()
        {
            var config = new Configuration();

            config.Configure();
            config.AddAssembly(typeof (Product).Assembly);
            HbmSerializer.Default.Validate = true;
            var stream = HbmSerializer.Default.Serialize(typeof (Product).Assembly);
            stream.Position = 0;
            config.AddInputStream(stream);

            new SchemaUpdate(config).Execute(false, true);

            _sessionFactory = config.BuildSessionFactory();
            _sessionFactory.OpenSession();
        }
    }

    public interface IUnitOfWork : IDisposable
    {
    }

    internal class UnitOfWork : IUnitOfWork
    {
        public UnitOfWork(ISession session)
        {
            if (session == null) throw new ArgumentNullException(nameof(session));
            Session = session;
        }

        public ISession Session { get; private set; }

        public void Dispose()
        {
            Session.Dispose();
            Session = null;
        }
    }

    public interface IRepository<T> where T : class
    {
        void SaveOrUpdate(T obj);
    }

    public class Repository<T> : IRepository<T> where T : class
    {
        private readonly UnitOfWork _uow;

        public Repository(IUnitOfWork uow)
        {
            if (uow == null) throw new ArgumentNullException(nameof(uow));
            _uow = uow as UnitOfWork;
            if (_uow == null)
            {
                throw new ArgumentException("Этот репозиторий принимает только единицу работы NHibernate");
            }
        }

        private ISession Session
        {
            get { return _uow.Session; }
        }

        public void SaveOrUpdate(T obj)
        {
            Session.SaveOrUpdate(obj);
        }
    }
}

Answer the question

In order to leave comments, you need to log in

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question