Изучал использования NHibernate и паттернов и в итоге пришел к такому коду, это тестовый набросок, хочу подобное использовать в одном солюшене в котором будут два проекта, один в виде сервисов, другой в виде ASP.NET MVC. Задаю вопрос с целью понять, правильно ли я понял эти паттерны, правильно ли их использовал и не лишние ли они вообще и можно было все не усложнять?
Исходный код (в виде одного файла, для запуска необходимы пакеты System.Data.SQLite, NHibernate, NHibernate.Mapping.Attributes):
spoilerusing 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);
}
}
}