如何处理动作过滤器?

Cra*_*erz 1 dependency-injection castle-windsor asp.net-mvc-3 asp.net-mvc-4

我有以下全局过滤器,ISiteValidation和ICacheService通过Windsor容器注入并设置为Transient,因此容器不会自动处理依赖项.当站点投入生产时,这将导致资源问题.那么人们正在做什么来正确处理注入过滤器的资源?两个接口都是IDisposable,但是当Action Filter超出范围并且容器将继续保持实现时,Dispose永远不会被调用.

public class SiteValidationAttribute : ActionFilterAttribute
{
    public ISiteValidation SiteValidation { get; set; }
    public ICacheService CacheService { get; set; }

    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        if (filterContext.RequestContext.HttpContext.Request.Url != null)
        {
            string host = filterContext.RequestContext.HttpContext.Request.Url.Host;
            try
            {
                string siteId = CacheService.Get("SiteId",
                                                 () =>
                                                 SiteValidation.GetSiteId(
                                                     host));
                var siteIdCookie = new HttpCookie("_site") {Value = siteId};
                filterContext.RequestContext.HttpContext.Response.Cookies.Add(siteIdCookie);
            }
            catch (Exception)
            {
                throw new HttpException(404, String.Format("This site'{0}' was not found", host));
            }
        }

        base.OnActionExecuted(filterContext);
    }
}
Run Code Online (Sandbox Code Playgroud)

Rem*_*oor 5

属性由CLR根据请求创建:

如果要构造属性对象,则必须调用GetCustomAttributes或GetCustomAttribute.每次调用其中一个方法时,它都会构造指定属性类型的新实例,并根据代码中指定的值设置每个实例的字段和属性.

这意味着它们不在任何IoC容器的控制范围内.可能处置这些系统的唯一部分是调用一个GetCustomAttributeGetCustomAttributes.但没有任何明确的做法; 因此,属性不应该是Disposable.

幸运的是,还有另一种方式.不要使用过滤器的属性,而是在需要时实现IActionFilter并注册一个IFilterProvider返回过滤器的新实例(由IoC容器创建).

看看如何使用Ninject完成它; 相同的方法应该可以移植到温莎.

https://github.com/ninject/ninject.web.mvc/tree/master/mvc3/src/Ninject.Web.Mvc/Filter