2017-02-16 2 views
0

Château windsor est utilisé dans l'application MVC comme il est décrit ici: Plugging Windsor in MVCCastle proxy windsor générons fuite de mémoire

Dans ma demande il y a une différence et qui est la méthode AddControllerLoggingFunctionality:

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

Cette méthode est en classe de l'enregistreur:

[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())); 
    } 
} 

Et quelqu'un peut-il expliquer cela? Pourquoi IController peut-il appeler AddControllerLoggingFunctionality et que fait-il?

En raison de ce changement, ces contrôleurs ne sont jamais libérés de la mémoire (quand container.Kernel.ReleaseComponent (contrôleur) est appelé) et je reçois une fuite de mémoire. Le compteur "Object tracked by release policy" augmente tout le temps. Si je supprime AddControllerLoggingFunctionality, le compteur "Object tracked by release policy" diminue chaque fois que j'appelle ReleaseComponent et que la fuite de mémoire ne se produit pas.

+0

Que faire AddControllerLoggingFunctionality, pouvez-vous inclure le code source? –

+0

Désolé, j'ai joint la mauvaise méthode. Maintenant, j'ai inclus le bon. Je ne suis pas sûr de ce qu'il fait réellement - je ne suis pas familier avec le proxy dynamique. Pour l'instant ce serait bien au moins si je sais comment je peux disposer du contrôleur (libérer la mémoire). – Simon

Répondre

2

Vous n'appelez pas le Release() sur le contrôleur mais vous l'appelez sur le proxy que vous avez créé manuellement. Release() est donc une interdiction d'accès à Windsor car il ne connaît pas cet objet et continue donc de suivre le composant du contrôleur.

Si vous utilisez le built-in interception support de Windsor, vous n'avez pas à vous inquiéter de ce problème car Windsor saura comment se débarrasser du composant lorsqu'il aura son propre proxy géré en interne.

Si vous voulez tester cela avant de passer à la prise en charge intégrée de Windsor, CAST votre procuration à Castle.DynamicProxy.IProxyTargetAccessor et appeler DynProxyGetTarget() pour obtenir votre instance de contrôleur que vous devrez passer à Release().

(Cette réponse est copiée de notre discussion sur la liste de diffusion des utilisateurs Château)