2011-10-14 1 views
3

Est-il possible de conserver une référence à un assemblage d'un autre domaine sans que cet assemblage ne soit chargé dans le domaine actuel?Assemblage de l'assemblage à partir d'un autre AppDomain

Je travaille sur la réparation d'une fuite de mémoire dans un service Windows qui génère dynamiquement des assemblys et exécute le code généré dynamiquement. Le problème est que les assemblys générés sont chargés dans le domaine de l'application actuelle et ne peuvent jamais être déchargés.

Il y a une méthode dans l'une des bibliothèques de services Windows qui a la signature suivante:

public Assembly CreateMethod(ObservableCollection<Field> sourceFields, Field destinationField) 

Cette méthode crée le code pour l'assemblage et la charge avec la fonction LoadMethod bibliothèque CSScript:

result = CSScript.LoadMethod(scriptFunction.ToString()); 

Plus tard, la référence d'assemblage de CreateMethod est utilisée pour exécuter une fonction dans l'assembly généré.

public object Run(Field destinationField, ObservableCollection<LinkField> sourceLinkFields, DataRow mainRow, Assembly script) { 

    ... 

    var method = script.GetStaticMethodWithArgs("*.a" + Id.ToString().Replace("-", String.Empty), argumentTypes.ToArray()); 

    return method(arguments.ToArray()); 
} 

Je me demande s'il est possible de charger l'assembly généré dynamiquement dans un autre domaine d'application et de les exécuter par un certain type de procuration sans l'avoir chargé dans le domaine de l'application actuelle.

Edit:

Je veux savoir si je peux utiliser une référence de classe Assembly dans un AppDomain lorsque l'ensemble est chargé dans un autre AppDomain. En regardant la documentation MSDN, ils montrent comment utiliser MarshalByRefObject. Fondamentalement, j'essaie d'éviter de changer la signature de ma fonction CreateMethod, mais il se peut que je devrais la changer pour retourner MarshalByRefObject si ce n'est pas possible.

Mise à jour:

J'ai fini par mettre l'appel à CSScript.LoadMethod dans l'autre application domaine où je garde un dictionnaire, je puis fait CreateMethod retourner un Guid au lieu d'une Assemblée, puis je passe cette Guid autour jusqu'à l'appel Run. L'appel Exécuter prend maintenant un Guid comme argument au lieu d'un assemblage. Dans l'appel Run, je passe le Guid à l'autre domaine de l'application, exécute la méthode et renvoie l'objet result via une classe qui hérite de MarshalByRefObject.

+0

Voir par exemple: http: // stackoverflow.com/questions/88717/chargement-dlls-dans-un-domaine-distinct – DeCaf

Répondre

1

Si vous ne voulez pas l'assemblage dynamique dans votre principale AppDomain, vous devez déplacer CreateMethod à un autre AppDomain, parce que dès que vous avez une instance de Assembly, il a été chargé. En d'autres termes, il n'est pas possible de conserver une référence à un assembly dans un autre domaine d'application, uniquement pour appeler cet assembly à travers les domaines d'application.

Sans changer la signature et un tas de votre code, il semble que vous devez déplacer le montant minimum: 1) création de l'assemblage et 2) Run. Ensuite, avoir la mise en œuvre de Run marshall les résultats.

En ce qui CreateMethod Je pense que vous voulez une méthode dans l'autre ensemble pour « envelopper » CreateMethod et retourner une sorte de jeton qui peut être transmis à Run. C'est presque comme changer la signature d'une manière ...

+0

Merci, c'était l'approche que j'ai fini par prendre. J'ai dû modifier les signatures de méthodes CreateMethod et Run, mais j'étais toujours capable de conserver la conception d'origine du code. – dmck

1

Ceci est l'une des principales caractéristiques d'un AppDomain! Il suffit d'aller consulter la documentation

+0

Merci pour le lien, j'ai mis à jour la question avec quelques détails supplémentaires. Je ne suis toujours pas clair si j'ai besoin de changer la signature de CreateMethod à MarshalByRefObject ou si je peux garder le type de retour comme Assemblée – dmck

+0

Dans l'intérêt d'aider les autres à l'avenir, je voudrais savoir: aviez-vous déjà regardé la documentation pour 'AppDomain'? –

Questions connexes