你应该如何在我的asp.net-mvc网站上使用UnitofWork模式(使用nhibernate和ninject)

leo*_*ora 11 nhibernate ninject ioc-container unit-of-work asp.net-mvc-3

我已经按照这个网站上的模式将ninject和nhibernate连接到我的asp.net-mvc3网站.

这是我的global.aspx.cs中的代码:

 internal class ServiceModule : NinjectModule
{
    public override void Load()
    {
        var helper = new NHibernateHelper(connectionString);
        Bind<ISessionFactory>().ToConstant(helper.SessionFactory)
            .InSingletonScope();

        Bind<IUnitOfWork>().To<UnitOfWork>()
            .InRequestScope();
        Bind<ISession>().ToProvider(new SessionProvider())
            .InRequestScope();
        Bind<IIntKeyedRepository<FAQ>>().To<Repository<FAQ>>()
            .InRequestScope();
       }
Run Code Online (Sandbox Code Playgroud)

问题是我现在需要在我的控制器中执行Update()和Add();

我有这个作为我的控制器代码:

    public FAQController(IIntKeyedRepository<FAQ> faqRepository, IUnitOfWork unitOfWork)
    {
        _faqRepository = faqRepository;
        _unitOfWork = unitOfWork;
    }


  [Authorize]
    [AcceptVerbs(HttpVerbs.Post)]
    [ValidateInput(false)]
    public ActionResult AddFAQ(FAQ contact)
    {
        var c = new FAQ {Question = contact.Question, Answer = contact.Answer};
        _faqRepository.Add(c);
        _unitOfWork.Commit();
        return RedirectToAction("Index");
    }
Run Code Online (Sandbox Code Playgroud)

我的主要问题是,在构造函数中传递Iunitofwork感觉不对,因为许多其他操作不需要它.我只是需要它来执行更新和插入我的数据库的操作.由于我在上面的链接上使用ninject IOC,似乎可以说通过IOC传递这个unitofwork对象.

那么,在asp.net-mvc中使用带有IOC的UnitOfWork模式是否有一种更好的更优化方式,它可以为我的控制器中的每个方法调用istransaction.

Rem*_*oor 12

处理事务的另一种方法是使用IActionFilterOpen in transaction in OnActionExecutingand commit onOnActionExecuted

public class TransactionFilter : IActionFilter
{
    private readonly ISession session;
    private ITransaction transaction;

    public TransactionFilter(ISession session)
    {
        this.session = session;
    }

    public void OnActionExecuting(ActionExecutingContext filterContext)
    {
        this.transaction = this.session.BeginTransaction();
    }

    public void OnActionExecuted(ActionExecutedContext filterContext)
    {
        try
        {
            if (this.transaction.IsActive)
            {
                if (filterContext.Exception == null)
                {
                    this.transaction.Commit();
                }
                else
                {
                    this.transaction.Rollback();
                }
            }
        }
        finally
        {
            this.transaction.Dispose();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

定义属性以标记使用事务的操作:

[AttributeUsage(AttributeTargets.Method)]
public class TransactionAttribute : Attribute
{ 
}
Run Code Online (Sandbox Code Playgroud)

更改您的Ninject配置:

internal class ServiceModule : NinjectModule
{
    public override void Load()
    {
        var helper = new NHibernateHelper(connectionString);
        Bind<ISessionFactory>().ToConstant(helper.SessionFactory)
            .InSingletonScope();

        Bind<ISession>().ToProvider<SessionProvider>().InRequestScope();
        Bind(typeof(IRepository<>)).To(typeof(Repository<>));
        Bind(typeof(IIntKeyedRepository<>)).To(typeof(Repository<>));
        BindFilter<TransactionFilter>(FilterScope.Action, null)
            .WhenActionMethodHas<TransactionAttribute>();
    }
}
Run Code Online (Sandbox Code Playgroud)

最后改变你的控制器:

public FAQController(IIntKeyedRepository<FAQ> faqRepository)
{
    _faqRepository = faqRepository;
}


[Transaction]
[Authorize]
[AcceptVerbs(HttpVerbs.Post)]
[ValidateInput(false)]
public ActionResult AddFAQ(FAQ contact)
{
    var c = new FAQ {Question = contact.Question, Answer = contact.Answer};
    _faqRepository.Add(c);
    return RedirectToAction("Index");
}
Run Code Online (Sandbox Code Playgroud)