Quel est le chemin le plus court pour mettre en œuvre une procuration ou une catégorie d'décorateur en c #?

StackOverflow https://stackoverflow.com/questions/508110

Question

Lorsque vous avez une voiture de classe qui implémente IVehicle et que vous voulez envelopper dans un décorateur qui transmet tous les appels à la voiture et les compte, comment le feriez-vous?

Dans Ruby je pouvais construire un décorateur sans méthodes et utiliser method_missing pour transférer tous les appels à l'objet de la voiture.

En Java je pourrais construire un objet proxy qui exécute tout le code par une méthode et transmet ensuite.

Y at-il quelque chose similaire que je peux faire en C #?


Mise à jour:

sur la base des answeres et lire sur ce que System.Reflection.Emit Ive il devrait être possible d'écrire une méthode similaire à ceci:

Type proxyBuilder(Type someType, delagate functionToBeApplied, Object forward)

où type implémente toutes les interfaces de UnType, exécute functionToBeApplied et transmet l'appel de méthode pour objet tout en retournant son retour.

Y at-il lib qui fait exactement cela ou devrais-je écrire mon propre?

Était-ce utile?

La solution

Pour vous mandatement pouvez regarder dans « RealProxy » si vous voulez utiliser des types standard, il est un peu compliqué à utiliser si (et il a besoin de vos classes héritent de MarshalByRefObject).

public class TestProxy<T> : RealProxy where T : class
{
    public T Instance { get { return (T)GetTransparentProxy(); } }
    private readonly MarshalByRefObject refObject;
    private readonly string uri;

    public TestProxy() : base(typeof(T))
    {
        refObject = (MarshalByRefObject)Activator.CreateInstance(typeof(T));
        var objRef = RemotingServices.Marshal(refObject);
        uri = objRef.URI;
    }

    // You can find more info on what can be done in here off MSDN.
    public override IMessage Invoke(IMessage message)
    {
        Console.WriteLine("Invoke!");
        message.Properties["__Uri"] = uri;
        return ChannelServices.SyncDispatchMessage(message);
    }
}

Sinon, vous pourriez obtenir « DynamicProxy » du château .. Il fonctionne un peu mieux dans mon expérience ..

Si vous utilisez un de ceux que vous ne neccessarily obtenir d'excellentes performances bien, je les utilise principalement dans les appels qui seront probablement lente en premier lieu .. Mais vous pouvez l'essayer si vous voulez.

La solution de Marc aura de meilleures performances.

Autres conseils

Malheureusement, il n'y a pas de soutien mixin en C #. Donc, vous aurez besoin de mettre en œuvre toutes les méthodes, ou utiliser un Reflection.Emit lourd devoir de le faire. L'autre alternative est un (en option) classe proxy / base de décorateur ...

abstract class FooBase : IFoo {
   protected FooBase(IFoo next) {this.next = next;}
   private readonly IFoo next;
   public virtual void Bar() { // one of the interface methods
       next.Bar();
   }
   public virtual int Blop() { // one of the interface methods
       return next.Blop();
   }
   // etc
}

puis

class SomeFoo : FooBase {
   public SomeFoo(IFoo next) : base(next) {}
   public override void Bar() {...}
}

Faisant observer que l'utilisation du est strictement facultative FooBase; tout IFoo est autorisé.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top