NHibernateUnitOfWork + ASP.Net MVC - PullRequest
0 голосов
/ 20 мая 2010

Я впервые с DDD, так что я новичок! Итак, давайте это очень просто: D Я разработал приложение, используя asp.net mvc 2, ddd и nhibernate. У меня есть модель предметной области в библиотеке классов, мои репозитории в другой библиотеке классов и приложение asp.net mvc 2. Мой базовый класс репозитория, у меня есть конструкция, которую я внедряю и зависимость (мой уникальный объект ISessionFactory запущен в global.asax), код:

public class Repository<T> : IRepository<T>
    where T : Entidade
{
    protected ISessionFactory SessionFactory { get; private set; }
    protected ISession Session
    {
        get { return SessionFactory.GetCurrentSession(); }
    }

    protected Repository(ISessionFactory sessionFactory)
    {
        SessionFactory = sessionFactory;
    }        

    public void Save(T entity)
    {
        Session.SaveOrUpdate(entity);
    }

    public void Delete(T entity)
    {
        Session.Delete(entity);
    }

    public T Get(long key)
    {
        return Session.Get<T>(key);
    }

    public IList<T> FindAll()
    {
        return Session.CreateCriteria(typeof(T)).SetCacheable(true).List<T>();
    }
}

И после того, как у меня появятся специальные хранилища, вроде этого:

public class DocumentRepository : Repository<Domain.Document>, IDocumentRepository
{
        // constructor
        public DocumentRepository (ISessionFactory sessionFactory) : base(sessionFactory) 
        { }

        public IList<Domain.Document> GetByType(int idType)
        {
            var result = Session.CreateQuery("from Document d where d.Type.Id = :IdType")
                .SetParameter("IdType", idType)
                .List<Domain.Document>();

            return result;
        }
}

В этом коде нет управления транзакциями, и он работает нормально, но я хотел бы сделать что-то для управления этими репозиториями в моем контроллере asp.net mvc, что-то простое, например:

using (var tx = /* what can I put here ? */) {
   try 
   {
     _repositoryA.Save(objA);
     _repositoryB.Save(objB);
     _repositotyC.Delete(objC);
     /* ... others tasks ... */

     tx.Commit();
   }
   catch
   {
     tx.RollBack();
   }
}

Я слышал о NHibernateUnitOfWork, но я не знаю :(, Как я могу настроить NHibernateUnitOfWork для работы с моими репозиториями? Должен ли я изменить мой простой репозиторий? Предложения приветствуются!

Так что, спасибо, если кто-то прочитал здесь! Если можете мне помочь, я оцениваю!

PS: простите за мой английский!

пока = D

Ответы [ 3 ]

2 голосов
/ 20 мая 2010

Сессия - это единица работы NHibernate.Но вы всегда можете создать свою собственную абстракцию.

using (var tx = Session.BeginTransaction) { ...
1 голос
/ 21 мая 2010

Существует отличная библиотека под названием NCommon ( source ), которая предоставляет великолепную встроенную реализацию UnitOfWork. Версия 1.1 позволяет вам делать что-то вроде:

public class Foo
{
    private readonly IRepository<Stuff> _repository;

    public Foo(IRepository<Stuff> repository)
    {
         _repository = repository;
    }

    public void DoSomething()
    {
        using (var scope = new UnitOfWorkScope())
        {
           _repository.Save(a);
           scope.Commit();
        }
    }
}

Он интегрируется с последним NHibernate и даже использует NHibernate.Linq для предоставления некоторых мощных функций запросов. У вас мало или вообще ничего, чтобы построить себя, и он отлично работает из коробки.

Edit:

Я подробно остановился на своем примере, чтобы показать полный рекомендуемый способ использования NCommon в проекте с внедрением зависимостей.

1 голос
/ 20 мая 2010

Вы можете сделать Сессию в своем Репозитории общедоступной собственностью. Тогда вы можете сделать следующее:

using(var tx = _repository.Session.BeginTransaction())

В некоторой степени связанной заметки, все это должно быть внутри уровня сервиса, а не в вашем контроллере. Тогда у контроллера должны быть ссылки на ваши сервисы.

...