2017-02-16 51 views
0

城堡溫莎在MVC申請中使用,因爲它是在此描述: Plugging Windsor in MVC城堡溫莎代理生成存儲器泄漏

在我的應用程序有一點不同,就是方法AddControllerLoggingFunctionality:

var controller = ((IController)container.Kernel.Resolve(controllerType)).AddControllerLoggingFunctionality(); 

此方法在記錄器類:

[DebuggerStepThrough] 
public static class Logger 
{ 
    private static readonly Castle.DynamicProxy.ProxyGenerator proxyGenerator; 
    static Logger() 
    { 
     proxyGenerator = new Castle.DynamicProxy.ProxyGenerator(); 
     Castle.DynamicProxy.Generators.AttributesToAvoidReplicating.Add(
      typeof(ServiceContractAttribute)); 
    } 

    public static TInterface AddControllerLoggingFunctionality<TInterface>(this TInterface implementation) 
     where TInterface : class 
    { 
     if (implementation == null) 
     { 
      throw new ArgumentNullException("implementation"); 
     } 

     if (!typeof(TInterface).IsInterface) 
     { 
      throw new Exception("Type of 'TInterface' must be interface."); 
     } 

     Castle.DynamicProxy.ProxyGenerationOptions options = 
      new Castle.DynamicProxy.ProxyGenerationOptions(); 

     var origAttribs = implementation.GetType().GetCustomAttributesData(); 
     if (origAttribs != null) 
     { 
      foreach (var origAttrib in origAttribs) 
      { 
       options.AdditionalAttributes.Add(
        AttributeUtil.CreateBuilder(origAttrib)); 
      } 
     } 

     return (TInterface)proxyGenerator.CreateInterfaceProxyWithTarget<TInterface>(
      implementation, 
      options, 
      new ControllerLoggingInterceptor(implementation.GetType())); 
    } 
} 

而且 有人能解釋一下嗎?爲什麼IController可以調用AddControllerLoggingFunctionality,它是什麼?

由於這一變化,該控制器被從未從存儲器釋放(當 container.Kernel.ReleaseComponent(控制器);被調用),我得到內存泄漏。 「釋放策略跟蹤的對象」計數器一直在增加。 如果我刪除了AddControllerLoggingFunctionality,那麼當我調用ReleaseComponent並且內存泄漏沒有發生時,每次「由發佈策略跟蹤的對象」計數器都會減少。

+0

是什麼AddControllerLoggingFunctionality做,你能包括源代碼(這個答案是從我們的discussion城堡用戶郵件列表上覆印)? –

+0

對不起,我附上了錯誤的方法。現在我已經包括了正確的一個。我不確定它實際做了什麼 - 我不熟悉動態代理。 現在,至少如果我知道如何處置控制器(釋放內存),這將是很好的。 – Simon

回答

2

您不是在控制器上調用Release(),而是在您手動創建的代理上調用它,因此Release()對Windsor來說只是一個不適用的操作,因爲它不知道該對象,因此一直跟蹤控制器組件。

如果您使用Windsor的built-in interception support,您不必擔心這個問題,因爲Windsor會在通過自己的內部託管代理時知道如何處置該組件。

如果您想在更改爲Windsor的內置支持之前對其進行測試,請將代理投入Castle.DynamicProxy.IProxyTargetAccessor並致電DynProxyGetTarget()獲取您需要傳遞給Release()的控制器實例。