2017-02-16 4 views
0

城ウィンザーは、MVCアプリケーションで使用されるリーク発生しますロガークラスである:城ウィンザープロキシは、メモリは、それがここで説明されているよう

[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(controller);が呼び出されたとき)、メモリリークが発生します。 「リリースポリシーによって追跡されるオブジェクト」カウンタは常に増加します。 AddControllerLoggingFunctionalityを削除した場合、ReleaseComponentを呼び出してメモリリークが発生しないたびに「リリースポリシーで追跡されるオブジェクト」カウンタが減少します。

+0

AddControllerLoggingFunctionalityは何をするのか、あなたがソースコードを含めることができますか? –

+0

申し訳ありませんが、私は間違った方法を付けました。今私は正しいものを含めました。私はそれが実際に何をするか分からない - 私は動的プロキシに精通していない。 今のところ、コントローラ(リリースメモリ)をどのように処分できるか分かっていれば、少なくともそれはいいと思います。 – Simon

答えて

2

Release()はコントローラ上では呼び出されませんが、手作業で作成したプロキシで呼び出しているため、Release()はそのオブジェクトについて知らないため、コントローラコンポーネントを追跡し続けます。

ウィンザーのbuilt-in interception supportを使用している場合、ウィンザーは独自の内部管理プロキシを渡したときにコンポーネントを廃棄する方法を知っているため、この問題については心配する必要はありません。

Windsorのビルトインサポートに変更する前にこれをテストする場合は、Castle.DynamicProxy.IProxyTargetAccessorにキャストし、に渡す必要があるコントローラインスタンスを取得するためにDynProxyGetTarget()を呼び出します。

(この答えはメーリングリスト城のユーザーに私達のdiscussionからコピーされます)

関連する問題