46 votes

Implémentation dynamique d'une interface dans .NET 4.0 (C #)

Avec les nouvelles capacités dynamiques dans .NET 4.0, il me semble qu'il devrait être possible de mettre en œuvre de manière dynamique une interface, par exemple, avec:

public interface IFoo 
{
    string Bar(int baz);
}

public class Foo : IFoo
{
    public string Bar(int baz) { return baz.ToString(); }
}

public class Proxy : IDynamicMetaObjectProvider
{
    private readonly object target;

    public Proxy(object target) { this.target = target; }

    // something clever goes here
}

Ensuite, je l'espère, il y a un moyen de rendre possible l'écriture:

dynamic proxy = new Proxy(new Foo());
IFoo fooProxy = (IFoo)proxy; // because the target object implements it
string bar = fooProxy.Bar(123); // delegates through to the target implementation

Mais, encore, je ne suis pas sûr de ce que pour remplacer // something clever goes here avec.

Donc, mes questions sont les suivantes:

  1. Est-ce réellement possible de faire avec la dynamique de l'exécution? Il apparaît que de façon dynamique la mise en œuvre de choses comme des méthodes et des propriétés est assez facile, mais je n'ai trouvé aucune documentation sur dynamiquement la mise en œuvre des interfaces et des conversions à eux.

  2. En supposant que cela est possible, comment est-il difficile susceptible d'être? (Vous pouvez supposer que je suis un décent programmeur avec beaucoup d'expérience des choses comme réflexion, mais de nouveau à la dynamique du cadre.)

  3. Existe-il des ressources qui pourraient aider à me diriger dans la bonne direction pour la mise en œuvre de quelque chose comme cela? Ou même les échantillons où ce genre de chose a déjà été fait, je peux l'utiliser comme un point de départ?

44voto

jbtule Points 11159

Le framework opensource Impromptu-Interface a été conçu pour cela. Il génère un proxy léger mis en cache avec une interface statique et utilise le dlr pour transférer l'appel à l'objet d'origine.

 using ImpromptuInterface;

public interface ISimpeleClassProps
{
    string Prop1 { get;  }

    long Prop2 { get; }

    Guid Prop3 { get; }
}
 

-

 dynamic tOriginal= new ExpandoObject();
tOriginal.Prop1 = "Test";
tOriginal.Prop2 = 42L;
tOriginal.Prop3 = Guid.NewGuid();

ISimpeleClassProps tActsLike = Impromptu.ActLike(tOriginal);
 

14voto

Nicole Calinoiu Points 14034

Autant que je sache, il n'est pas possible sans intervention manuelle de l'écrire ou de générer du code qui transmet les membres d'interface à la enveloppé d'instance. Si vous souhaitez voir Microsoft a fourni un soutien pour ce genre de chose, vous pourriez envisager de vote à https://connect.microsoft.com/VisualStudio/feedback/details/526307/add-automatic-generation-of-interface-implementation-via-implementing-member .

7voto

Brian Genisio Points 30777

Je pense avoir écrit une bibliothèque qui fait ce que vous voulez ... Elle s’appelle DynamicWrapper (sur CodePlex) et encapsule automatiquement une classe pour qu’elle implémente une interface. c'est ce que tu veux?

3voto

stephbu Points 4440

Le cast explicite, as, et is échouer en raison du type de comparaison à l'encontre de votre proxy de la classe de base, mais implicite casting peut déclencher DynamicObject.TryConvert, de sorte que vous pouvez ensuite revenir objet interne en lieu et place de l'objet dynamique.
- TryConvert Documentation MSDN

Alors que le code ci-dessous fonctionne, ce n'est pas l'interface de délégation en soi, la seule exposition d'état interne. Il semble que vous pourriez être à la recherche de quelque chose comme une interception motif comme celui de Brian DynamicWrapper.

dynamic wrapper = new Proxy(new Foo());
IFoo foo = wrapper;
foo.Bar();

class Proxy : DynamicObject
{
    ...

    public override bool TryConvert(ConvertBinder binder, out object result)
    {
        Type bindingType = binder.Type;
        if (bindingType.IsInstanceOfType(target))
        {
            result = target;
            return true;
        }
        result = null;
        return false;

    }

}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X