Solution: le domaine d'application .net ne fait que transmettre des objets par valeur
-
11-07-2019 - |
Question
Je développe une application .net qui dépend énormément des plugins. L’application elle-même contient une connexion à un serveur distant.
Récemment, j'ai creusé dans les domaines d'application et je les considère comme la solution idéale pour isoler le code du plug-in du reste de l'application.
Cependant, il existe un gros inconvénient qui me empêche d’implémenter les domaines d’application pour héberger les plugins. Il semble qu'il n'y ait aucun moyen de transmettre un objet par référence à un autre domaine d'application, nécessaire pour transmettre une référence à l'objet de connexion.
J'espérais que quelqu'un pourrait me donner une solution de contournement afin que je puisse transmettre une référence à cet objet.
Remarque: la création d'un proxy est hors de question, la couche de connexion joue déjà un rôle de proxy car les classes sont générées automatiquement.
Note2: System.AddIn ne peut pas être utilisé car il n’est pas disponible sur le framework compact.
La solution
Avez-vous essayé de dériver de MarshalByRefObject ? C’est pénible de gâcher la hiérarchie de votre héritage, mais je pense que c’est ce que vous voulez.
À partir de la documentation:
MarshalByRefObject est la classe de base pour les objets qui communiquent entre limites du domaine d'application par échanger des messages en utilisant un proxy. Objets qui n'héritent pas de MarshalByRefObject sont implicitement marshal par valeur. Quand une télécommande application référence un marshal par objet de valeur, une copie de l'objet est passé à travers le domaine d'application limites.
Les objets MarshalByRefObject sont accessible directement dans le limites de l'application locale domaine. La première fois une application dans un domaine d'application distant accède à un MarshalByRefObject, un proxy est passé à l'application distante. Les appels suivants sur le proxy sont marshaled retour à l'objet résidant dans le domaine d'application local.
Les types doivent hériter de MarshalByRefObject lorsque le type est utilisé à travers le domaine d'application limites, et l'état de la objet ne doit pas être copié parce que le les membres de l'objet ne sont pas utilisables en dehors du domaine d'application où ils ont été créés.
Selon mon expérience, cela peut être assez limitant: vous devez vraiment faire le moins possible au-delà de la limite AppDomain, en vous limitant de préférence aux opérations qui nécessitent uniquement des types primitifs, des chaînes et des tableaux. C'est peut-être dû à ma propre inexpérience dans l'utilisation de plusieurs domaines d'application, mais c'est juste un avertissement: c'est un peu un champ de mines.
Autres conseils
Pour parler à la même instance entre AppDomains, elle doit hériter de MarshalByRefObject . Ainsi fait, chaque appel de méthode à l'objet (y compris les propriétés, etc.) est en réalité un appel à distance à l'autre domaine d'application. Est-ce que cela vous aide?
Sachez que le nettoyage des mandataires MarshalByRefObject
est nettoyé en fonction d'un bail. En bref, si vous n'utilisez pas l'objet pendant un temps spécifique, il sera récupéré. Vous pouvez contrôler cela en substituant InitializeLifetimeService
pour renvoyer un objet de bail qui correspond à vos besoins. Si vous renvoyez null
, vous désactivez effectivement le crédit-bail, puis l'objet n'est récupéré que lorsque le AppDomain est déchargé.