Внедрение IUnitOfWork в конструктор IRepository - PullRequest
2 голосов
/ 28 марта 2012

Я пытаюсь использовать Unity IoC с шаблонами единиц работы и репозитория, однако я изо всех сил пытаюсь понять, как мой репозиторий получит свой сеанс Nhibernate для выполнения своей работы ...

Ниже у меня есть IUnityContainer, который выполняет привязки IoC. Затем у меня есть репозиторий NHibernate, который должен быть снабжен сеансом ISession, который должен быть предоставлен из единицы работы NHibernate, но теперь я уверен, что могу сказать Единство, чтобы предоставить его в своем конструкторе ..

Я сделал привязку для IUnitOfWork к Nhib ..., но как передать это значение в IRepository RegisterType?

private static IUnityContainer BuildUnityContainer()
    {
        var container = new UnityContainer();
        NHibernateHelper helper = new NHibernateHelper();

        // register all your components with the container here
        // e.g. container.RegisterType<ITestService, TestService>();            

        container.RegisterControllers();
        container.RegisterType<IUnitOfWork, NHibernateUnitOfWork>(new HierarchicalLifetimeManager());
        container.RegisterInstance<ISessionFactory>(helper.SessionFactory);
        container.RegisterType<IRepository, NHibernateRepository>() ;

        return container;
    }



public class NHibernateRepository : IRepository
{

public NHibernateRepository(ISession session)
        {
            _session = session;
        }
}


    public class NHibernateUnitOfWork : IUnitOfWork
    {
        private readonly ISessionFactory _sessionFactory;
        private readonly ITransaction _transaction;
        public ISession Session { get; private set; }

        public NHibernateUnitOfWork(ISessionFactory sessionFactory)
        {
            _sessionFactory = sessionFactory;
            Session = _sessionFactory.OpenSession();
            Session.FlushMode = FlushMode.Auto;
            _transaction = Session.BeginTransaction(IsolationLevel.ReadCommitted);
        }
}

Ответы [ 2 ]

2 голосов
/ 28 марта 2012

Зарегистрируйте свой ISession с вашим IUnityContainer следующим образом:

container.RegisterType<ISession>(new InjectionFactory(c => c.Resolve<ISessionFactory>().OpenSession());

Затем, когда требуется ISession, ISessionFactory будет разрешен, и начнется сеанс.

В приложениях, над которыми я работаю, мы определяем наши репозитории и единицы работы следующим образом:

public class NhUnitOfWork : IUnitOfWork
{
    readonly ISession _session;

    public IRepository<T> GetRepository<T>() where T : class
    {
        return new NhRepository<T>(_session);
    }

    public NhUnitOfWork(ISession session)
    {
        _session = session;
    }

    public void Dispose()
    {
        // Dispose logic, i.e. save/rollback
    }
}

public class NhRepository<T> : IRepository<T> where T : class
{
    readonly ISession _session;

    public void Add(T item)
    {
        _session.Save(item);
    }

    public void Delete(T item)
    {
        _session.Delete(item);
    }

    public void Update(T item)
    {
        _session.Update(item);
    }

    public NhRepository(ISession session)
    {
        _session = session;
    }
}

Тогда ваши службы используют это примерно так:

public class MyService
{
    readonly Func<IUnitOfWork> _unitOfWorkFactory;

    public MyService(Func<IUnitOfWork> unitOfWorkFactory)
    {
        _unitOfWorkFactory = unitOfWorkFactory;
    }

    public void DoServiceStuff()
    {
        using(var uow = _unitOfWorkFactory())
        {
            var newUser = new User() { Username = "My User" };

            var userRepo = uow.GetRepository<User>();
            userRepo.Add(newUser);

            uow.Save();
        }
    }
}
0 голосов
/ 28 марта 2012

Вы хотите создать экземпляр «IRepository», вам нужно инициализировать отображение для всех его зависимостей. Сингл: "ISession"

...