En passant anonyme de type, comme les paramètres de la méthode
Dans mon architecture de plugin, je suis actuellement en train de passer d'un plugin nom (chaîne de caractères), le nom de la méthode (chaîne de caractères) et les paramètres (tableau d'objets) à mon plugin de service pour exécuter la méthode spécifiée et retourner le résultat (de type T).
Le plugin du service méthode execute peut être vu ci-dessous:
public TResult Execute<TResult>(string pluginName, string operation, params object[] input) {
MethodInfo method = null;
TResult result = default(TResult);
var plugin = _plugins.Enabled().FirstOrDefault(x => x.GetType().Name.Equals(pluginName, StringComparison.InvariantCultureIgnoreCase));
if (plugin != null) {
method = plugin.GetType().GetMethods().FirstOrDefault(x => x.Name == operation);
if (method != null) {
result = (TResult)method.Invoke(plugin, input);
}
}
return result;
}
Un exemple d'utilisation:
var url = AppHelper.PluginService.Execute<string>(
"ImagePlugin",
"GetImageUrl",
new object[] { image, size });
Ce que je préfère faire est de passer d'un type anonyme la place (comme je pense que c'est plus lisible) c'est à dire
var url = AppHelper.PluginService.Execute<string>(
"ImagePlugin",
"GetImageUrl",
new { image = image, targetSize = size });
Comment puis-je modifier ma méthode Execute de la carte de l'anonyme de type de propriétés à mon plugin paramètres de la méthode?
J'avais envisagé d'utiliser le nouveau type dynamique dans .net 4.0, mais je préfère définir mes paramètres sur le plugin méthode plutôt que d'accepter un objet dynamique.
Merci
Ben
[Mise à jour]
Après en regardant à travers la ASP.NET MVC code source, il semble assez simple à tirer de l'anonyme de type dans un objet dictionnaire par exemple RouteValueDictionary.
Avec l'aide de la réflexion, une expression linq est créé dynamiquement. Même si c'est une bonne mise en œuvre, je n'ai pas vraiment envie que tout cela supplémentaire de complexité.
Que par les commentaires ci dessous, je peux atteindre la lisibilité en spécifiant simplement mes paramètres en ligne (pas besoin de l'objet de déclaration de tableau):
var url = AppHelper.PluginService.Execute<string>("ImagePlugin", "GetImageUrl", image, size);
- Puisque vous utilisez
params
mot-clé, vous pouvez le faireimage, size
au lieu denew object[] { image, size }
. Il serait de la rendre plus lisible, et depuisInvoke
méthodes accepte tableau d'objet, je laisse la signature de la méthode telle qu'elle est.
Vous devez vous connecter pour publier un commentaire.
Il existe des moyens pour rendre cela possible, bien que je ne l'aurais pas des conseils de l'un d'eux.
Tout d'abord, vous pouvez utiliser la réflexion qui signifie que vous devez écrire beaucoup de supplémentaire (risque d'erreur de code dans votre
PluginService.Execute
méthode pour obtenir les valeurs que vous voulez.Deuxième, si vous connaissez les paramètres du type anonyme, vous êtes de passage à votre méthode, vous pouvez utiliser la technique décrite ici. Vous pouvez convertir en un autre type anonyme à l'intérieur de votre méthode qui a les mêmes propriétés. Ici est une autre description de la même technique de Jon Skeet.
Troisièmement, vous pouvez utiliser des classes de
System.ComponentModel
. Par exemple, ASP.NET MVC utilise cette. Il utilise la réflexion sous le capot. Toutefois, dans ASP.NET MVC soit la propriété noms sont bien connus (controller
etaction
par exemple) ou leurs noms n'ont pas d'importance parce qu'ils sont transmis en tant que-est à une méthode de contrôleur (id
par exemple).J'ai fini par trouver ce post qui illustre l'utilisation anonyme de types de dictionnaires. En utilisant cette méthode, vous pouvez passer le type anonyme comme un paramètre de méthode (objet) et d'accéder à ses propriétés.
Cependant, je voudrais aussi ajouter que lorsque l'on regarde le une nouvelle dynamique de fonctionnalités .net 4.0 tels que la ExpandoObject, il se sent beaucoup plus propre de passer d'une dynamique de l'objet en tant que paramètre:
Utilisation dynamique de l'objet pour les paramètres si vous souhaitez passer d'un type anonyme. La méthode d'exécution d'un plugin doit s'attendre à certaines propriétés d'un paramètre de l'objet afin de pouvoir travailler. Par l'utilisation de mot-clé dynamic compilateur C# sera demandé de ne pas effectuer de vérification de type sur un paramètre et permettra d'utiliser fortement typées de syntaxe dans le code du plugin. Les propriétés de résolution de nom se produire dans l'exécution, et si un objet passé n'ont pas les propriétés d'une exception sera levée.
Lire la suite dans ce post de blog
Cet exemple convertit objet anonyme à un dictionnaire:
Vous pouvez l'appeler comme ceci:
Si c'est un anonomous type de Linq, alors vous pouvez facilement le faire en passant IEnumerable.
Voici un exemple d'une méthode de réception de la
Bien sûr, puisque vous êtes à l'aide de la réflexion, alors vous pouvez voir les problèmes de performance les plus lents machiens ou si vous avez un grand IEnumerable ou un grand nombre de propriétés dans T.
Salut j'ai écrit un post à ce sujet:
http://blog.jorgef.net/2011/06/converting-any-object-to-dynamic.html
J'espère que ça aide.
Je l'ai fait une fois. Ce que vous pouvez faire est d'obtenir les paramètres attendus par la fonction par le biais de la réflexion. Ensuite, vous pouvez construire votre tableau de paramètres en faisant correspondre les noms dans le tableau des paramètres avec les touches de l'objet anonyme.
Espère que ça aide :-).
Tout d'abord, vérifier le Système.Complément de l'espace de noms, vous pouvez obtenir de l'aide.
Seconde, vous pouvez créer une interface de votre propre spécifique du nom de la méthode et des paramètres, et de laisser le plugin implémenter l'interface. Vous pouvez définir l'interface du plugin dans un projet différent qui peut être référencé dans l'application ainsi que le plugin projet.