Domanda

Quando si dispone di una macchina di classe che implementa IVehicle e si desidera avvolgerlo in un decoratore che inoltra tutte le chiamate a macchina e li conta, come si dovrebbe fare?

In Ruby ho potuto solo costruire un decoratore, senza alcun metodo e utilizzare method_missing per inoltrare tutte le chiamate all'oggetto auto.

In Java ho potuto costruire un oggetto proxy che corre tutto il codice attraverso un metodo e l'inoltra in seguito.

C'è qualche cosa simile che posso fare in C #?


Aggiornamento:

sulla base dei answeres e cosa Ive letto circa System.Reflection.Emit dovrebbe essere possibile scrivere un metodo simile a questo:

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

dove tipo implementa tutte interfaccia di sometype, esegue functionToBeApplied e quindi inoltra la chiamata al metodo di opporsi ritornando suo ritorno.

C'è qualche lib che fa proprio questo o avrei dovuto scrivere il mio?

È stato utile?

Soluzione

per l'inoltro si poteva guardare in "RealProxy", se si desidera utilizzare tipi standard, è un po 'di una seccatura da usare anche se (e richiede le vostre classi ereditano da 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);
    }
}

In alternativa si potrebbe ottenere "DynamicProxy" dal castello .. Funziona un po 'meglio nella mia esperienza ..

Se si utilizza uno di quelli non sarà neccessarily ottenere grandi prestazioni, però, li uso principalmente in chiamate che sarà probabilmente lenta, in primo luogo .. Ma si può provare se si desidera.

La soluzione di Marc avrà prestazioni migliori.

Altri suggerimenti

Purtroppo, non v'è alcun supporto mixin in C #. Così avresti bisogno di implementare tutti i metodi, o usare qualche pesanti Reflection.Emit per farlo. L'altra alternativa è un (opzionale) classe proxy / base decorator ...

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
}

poi

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

Notando che l'utilizzo del FooBase è strettamente facoltativa; qualsiasi IFoo è permesso.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top