Quelle est la meilleure façon de mettre en œuvre un proxy dynamique en C #?
-
15-10-2019 - |
Question
J'ai besoin de créer un proxy dynamique en C #. Je veux que cette classe pour envelopper une autre classe, et de prendre sur l'interface publique de lui, transférer les appels à ces fonctions:
class MyRootClass
{
public virtual void Foo()
{
Console.Out.WriteLine("Foo!");
}
}
interface ISecondaryInterface
{
void Bar();
}
class Wrapper<T> : ISecondaryInterface where T: MyRootClass
{
public Wrapper(T otherObj)
{
}
public void Bar()
{
Console.Out.WriteLine("Bar!");
}
}
Voici comment je veux l'utiliser:
Wrapper<MyRootClass> wrappedObj = new Wrapper<MyRootClass>(new MyRootClass());
wrappedObj.Bar();
wrappedObj.Foo();
pour produire:
Bar!
Foo!
Toutes les idées?
Quelle est la meilleure façon de le faire?
Quelle est la meilleure façon de le faire?
Merci beaucoup.
UPDATE
J'ai essayé suivant la recommandation de Wernight et mettre en œuvre ce en utilisant C # 4.0 proxies dynamiques. Malheureusement, je suis toujours bloqué. Le point de la procuration doit mimer l'autre interface qui est (normalement, habituellement) attendu. L'utilisation DynamicObject me demande de changer tous les clients de cette option pour utiliser « dynamique » au lieu de « ISecondaryInterface ».
Y at-il un moyen d'obtenir un objet proxy, de sorte que quand il enveloppe un A, il annonce (statiquement?) Qu'il prend en charge l'interface A; et quand il enveloppe B, il annonce que est l'interface de supports B?
MISE À JOUR 2
Par exemple:
class MySecretProxy : DynamicObject, ISecondaryInterface
{
public override void TryInvokeMember(...) { .. }
// no declaration of Bar -- let it be handled by TryInvokeMember
}
La solution
.NET 4 DynamicObject
peut vous aider à y parvenir.
Un peu plus tôt framework .NET peut utiliser:
- Aspect #
- Encase AOP
- Spring.NET
- Aspect.NET
- AspectDNG
- Dynamic Proxy
- Nouveau *
- Loom.NET
- PostSharp
Chacun de ces cadres utilisent un certain nombre techniques pour l'injection d'un code avant et après l'exécution d'un méthode. Ceux-ci tombent généralement dans 4 catégories.
- injection MSIL - nous ici le code MSIL dans inject le corps du procédé étant exécuté. (Forte Post)
- Injection dynamique Runtime - techniques comme le reflet nous invoquer des méthodes dynamiquement.
- injection constructeur de type - liés à l'injection d'exécution, nous créons un type basé sur le type que nous souhaitons aux demandes proxy, puis maréchal par ce type. (Proxy dynamique)
- injection conteneur - Les demandes passent à travers un récipient qui invoque le code avant et après notre méthode en cours d'exécution.
Je sais que Château du projet s Dynamic Proxy est souvent utilisé (comme dans Moq juste pour nommer un grand projet).
Répondre au sujet MISE À JOUR
Qu'est-ce que vous avez écrit ne compilera pas. dynamique Les procurations sont l'exécution du code généré, vous devrez créer une instance de béton de la classe que vous êtes mandatement d'une manière ou d'une autre. Peut-être que vous cherchez à faire AOP (programmation orientée aspect).
class MySecretProxy<T> : DynamicObject, T where T : new()
{
private T _instance = new T();
public override void TryInvokeMember(...) { ... }
}
MySecretProxy<Bar> bar;
Autres conseils
Avez-vous regardé DynamicProxy du projet Castle? Il peut fournir ce que vous essayez d'atteindre en fin de compte. Voir http://www.castleproject.org/dynamicproxy/index.html
Il est également open source pour que vous puissiez même fourchette si nécessaire.
Vous pouvez le faire avec RealProxy si le type de cible est une interface ou dérive de MarshalByRefObject.
Vous pouvez vouloir regarder Linfu qui contient un mécanisme de proxy dynamique.
Je sais que les proxys utilisés par NHibernate pour le chargement paresseux
Château
Linfu
Spring ByteCode