将UnitOfWork注入Repository构造函数

时间:2012-03-28 16:45:53

标签: c# nhibernate unity-container ioc-container unit-of-work

我正在尝试使用Unity IoC和工作单元&存储库模式,但我正在努力弄清楚我的存储库如何让它的Nhibernate会话来执行它的工作......

下面我有我的IUnityContainer来做我的IoC绑定..然后我的NHibernate repo需要提供一个ISession,它应该从NHibernate工作单元提供,但我现在肯定我怎么知道Unity在它的构造函数中提供它..

我已经将IUnitOfWork绑定到了Nhib ... one,但是如何在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 个答案:

答案 0 :(得分:2)

将您的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();
        }
    }
}

答案 1 :(得分:0)

您想要创建“IRepository”的实例,您需要初始化其所有依赖项的映射。它是单身:“ISession”