1

다음과 같은 전역 필터가 있습니다. 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); 
    } 
} 

답변

5

속성은 요청에 CLR에 의해 만들어집니다 : 당신이 속성 객체를 생성하려면

, 당신은 해당 GetCustomAttributes 또는 해당 GetCustomAttribute 중 하나를 호출해야합니다. 이 메서드 중 하나가 호출 될 때마다 지정된 특성 형식의 새 인스턴스를 생성하고 코드에 지정된 값을 기반으로 인스턴스의 필드와 속성 을 각각 설정합니다.

이것은 IoC 컨테이너가 제어 할 수 없음을 의미합니다. 폐기 할 수있는 시스템의 유일한 부분은 GetCustomAttribute 또는 GetCustomAttributes입니다. 그러나 이것을 명백하게하는 것은 없습니다. 그 결과, 속성은 일회용이 아니어야합니다.

다행히도 다른 방법이 있습니다. 필터에 속성을 사용하지 말고 대신 IActionFilter을 구현하고 필요에 따라 필터의 새 인스턴스 (IoC 컨테이너로 작성)를 반환하는 IFilterProvider을 등록하십시오.

Ninject를 사용하여 어떻게 수행되는지보십시오. 동일한 접근법이 Windsor에 이식 가능해야합니다.

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