我有以下全局过滤器,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);
}
}
答案 0 :(得分:5)
属性由CLR根据请求创建:
如果要构造属性对象,则必须调用其中一个 GetCustomAttributes或GetCustomAttribute。每次都是其中之一 调用方法,它构造指定的新实例 属性类型并设置每个实例的字段和属性 基于代码中指定的值。
这意味着它们不在任何IoC容器的控制之内。系统中唯一可以处理它们的部分是调用GetCustomAttribute
或GetCustomAttributes
的部分。但没有任何明确的做法;因此,属性不应该是Disposable。
幸运的是,还有另一种方式。不要使用过滤器的属性,而是实现IActionFilter
并注册IFilterProvider
,以便在需要时返回过滤器的新实例(由IoC容器创建)。
看看如何使用Ninject完成它;相同的方法应该可以移植到温莎。
https://github.com/ninject/ninject.web.mvc/tree/master/mvc3/src/Ninject.Web.Mvc/Filter