SessionPerWebRequest UoW SimpleInjector ActionFilterAttribute

时间:2016-01-25 02:01:43

标签: inversion-of-control ioc-container unit-of-work simple-injector

我正在使用SimpleInjector,并希望使用UnitOfWork创建UnitOfWorkFactory每WebRequest。

我想使用ActionLiterAttribute执行此操作,以便每个网络请求都会开始新的UnitOfWork

我唯一的问题是将IUnitOfWorkFactory传递给ActionFilterAttribute类。

网上有一个类似的问题,但有一个使用Ninject的解决方案,不幸的是SimpleInjection并不等同于Bind过滤器。

这是我到目前为止所做的,不确定它是否正确。

我创建了SessionPerRequestActionFilter

public class SessionPerRequestActionFilter : ActionFilterAttribute
{
    private readonly Func<IUnitOfWorkFactory> _unitOfWorkFactory;
    private IUnitOfWork _unitOfWork;

    public SessionPerRequestActionFilter(Func<IUnitOfWorkFactory> unitOfWorkFactoryProvider)
    {
        if (unitOfWorkFactoryProvider == null) throw new ArgumentNullException("_unitOfWorkFactory");

        _unitOfWorkFactory = unitOfWorkFactoryProvider;
    }        

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        var unitOfWorkFactory = _unitOfWorkFactory.Invoke();
        _unitOfWork = unitOfWorkFactory.BeginUnitOfWork();
    }

    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        if (filterContext.Exception == null)
            _unitOfWork.Commit();

        _unitOfWork.Dispose();
    }
}

然后我将其添加到GlobalFilters页面的Global.ascx,但对我在此处的操作方式不满意。请参阅下面的代码片段中的我的想法。

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); // <-- So First register all filters
    RouteConfig.RegisterRoutes(RouteTable.Routes);
    BundleConfig.RegisterBundles(BundleTable.Bundles);


    #region Initialize SimpleInjector
    var container = new Container();           

    InitializeContainer(container);            

    container.RegisterMvcControllers(Assembly.GetExecutingAssembly());            

    container.RegisterMvcIntegratedFilterProvider();

    new AppHost(container).Init();

    GlobalFilters.Filters.Add(new SessionPerRequestActionFilter(() => container.GetInstance<IUnitOfWorkFactory>())); // <-- Then in here I go and register the filter again.

    container.Verify();

    DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(container));
    #endregion                
}

当然有更好的方法吗?在Property Injection中使用SessionPerRequestActionFilter可能更合适吗?

或者最好从ActionFilter中移除此项并在UnitOfWork中实施BaseController,然后将工厂注入控制器?

我在网上看到了很多这样的例子,但不确定哪一个是更现代的方法。

0 个答案:

没有答案