2010-09-01 4 views
4

J'ai une valeur dynamique (implémentation de IDynamicMetaObjectProvider) à laquelle j'appellerais méthodes et propriétés.Appelez les membres d'un IDynamicMetaObjectProvider sans faire référence à Microsoft.CSharp.dll

Exemples que j'ai trouvés jusqu'à présent d'appeler des membres sur un type d'utilisation de valeur dynamique à partir de Microsoft.CSharp.dll, par exemple.

IDynamicMetaObjectProvider x = GetDynamicValue(); 
CallSite<Func<CallSite, object, object, object>> site = CallSite<Func<CallSite, object, object, object>>.Create(
      Binder.SetMember(
       Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags.None, 
       "Foo", 
       null, 
       new[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) } 
      ) 
     ); 
site.Target(site, x, 42); 

Je veux être en mesure d'invoquer un des membres de IDynamicMetaObjectProvider sans utiliser Microsoft.CSharp.dll. Notez que je ne parle pas d'utiliser le mot-clé dynamique C# sur tout ce qui concerne C# mais en utilisant un IDynamicMetaObjectProvider directement.

Notez également que l'utilisation de Reflection ne fonctionnera pas. La réflexion contourne la liaison d'appel dynamique et effectue simplement une réflexion sur le type sous-jacent. J'ai besoin d'une technique qui fonctionne avec n'importe quelle implémentation de IDynamicMetaObjectProvider.

+3

Mais pourquoi? N'est-ce pas un peu comme dire que je veux utiliser WPF sans faire référence à PresentationFramework.dll? – Josh

+0

Vous pouvez utiliser la réflexion, mais vous devez appeler les membres de System.Dynamic.DynamicObject en utilisant la réflexion. – Steven

+0

Je voudrais éviter la référence à Microsoft.CSharp.dll parce que c'est pour une bibliothèque et pas tout le monde utilise C# et veut utiliser une bibliothèque qui fait référence à une DLL spécifique C#. La réflexion ne fonctionnera pas car cela doit fonctionner avec n'importe quelle implémentation de IDynamicMetaObjectProvider, pas seulement DynamicObject. –

Répondre

3

Vous devez implémenter le vôtre CallSiteBinder car il n'y a pas de langage CallSiteBinders agnostique. Fondamentalement, l'idée est que le classeur gère les différences subtiles entre les informations fournies par vos langues d'appel pour choisir le bon membre à lier sur n'importe quel objet indépendamment de la langue. Comme ce n'est pas comme si un classeur CSharp ne peut pas se lier à un objet IronPython, la souplesse d'utilisation de différents classeurs, selon le langage des bibliothèques, dépend de la flexibilité que vous fournissez via votre bibliothèque. Étant donné l'exemple ci-dessus si vous n'autorisiez pas les consommateurs de la bibliothèque à modifier les paramètres de liant, vous pouvez utiliser le classeur CSharp si vous en offriez plus, il serait peut-être utile de désactiver le liant via une injection de dépendance ou une méthode surchargée . Cependant, je pense que CSharpBinder devrait être bon si vous voulez passer juste quelques-uns des paramètres de liant parce que le lieur csharp vous donne une assez bonne flexibilité de liaison (à la seule exception de ne pas être sur le point de changer de liaison être insensible à la casse), et c'est vraiment le meilleur choix pour les classeurs dans une bibliothèque générique, car c'est le seul classeur de langue inclus dans l'installation .net 4.0 et l'installation de Mono 2.8.