SessionPerWebRequest UoW SimpleInjector ActionFilterAttribute

天涯浪子 提交于 2020-01-15 19:11:10

问题


I am using SimpleInjector and want to create a UnitOfWork Per WebRequest Using an UnitOfWorkFactory.

I want to do this by using an ActionLiterAttribute so that every web request will begin a new UnitOfWork

The only problem that I have is to pass the IUnitOfWorkFactory to the ActionFilterAttribute class.

There is a similar question about this online but there is a solution given using Ninject, Unfortunately with SimpleInjection there is no equivalent to Bind a filter.

This is what I have done so far, not sure if it is correct.

I have created a 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();
    }
}

Then I added it to GlobalFilters in my Global.ascx page, but not happy with how I did it here. See my thoughts in the code snippet bellow.

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                
}

Surely there is a better way to do this? Is it perhaps more appropriate to use Property Injection in SessionPerRequestActionFilter?

Or is it perhaps better to remove this from the ActionFilter and implement the UnitOfWork in the BaseController then injecting the factory into the controller?

I have seen so many examples online but not sure which one is the more modern approach.

来源:https://stackoverflow.com/questions/34984021/sessionperwebrequest-uow-simpleinjector-actionfilterattribute

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!