Un autre que je vois beaucoup mentionné est EmitMapper .
adrianbanks
1
Et la colle? glue.codeplex.com Ressemble également à un grand projet, mais je ne l'ai pas encore essayé. Je le ferai cependant le mois prochain. J'ai également vu un projet appelé EmitMapper emitmapper.codeplex.com
en tant que créateur de ValueInjecter , je peux vous dire que je l'ai fait parce que je voulais quelque chose de simple et de très flexible
Je n'aime vraiment pas écrire beaucoup ou écrire beaucoup monkey codecomme:
Prop1.Ignore,Prop2.Ignore etc.CreateMap<Foo,Bar>();CreateMap<Tomato,Potato>(); etc.
ValueInjecter est quelque chose comme mozilla avec ses plugins, vous créez ValueInjections et les utilisez
il y a des injections intégrées pour aplatir, aplatir et certaines sont destinées à être héritées
et cela fonctionne plus dans un type d'aspect , vous n'avez pas besoin de spécifier toutes les propriétés 1 à 1, au lieu de cela, vous faites quelque chose comme:
prendre toutes les propriétés int de la source dont le nom se termine par "Id", transformer la valeur et définir chacune une propriété dans l'objet source avec le même nom sans le suffixe Id et son type est hérité d'Entity, des trucs comme ça
donc une différence évidente, ValueInjecter est utilisé même dans les formulaires Windows avec aplatissement et aplatissement, c'est à quel point il est flexible
(mappage de l'objet aux contrôles de formulaire et inversement)
Automapper, non utilisable dans les formulaires Windows, pas de non-aplatissement, mais il a de bonnes choses comme le mappage de collections, donc si vous en avez besoin avec ValueInjecter, vous faites juste quelque chose comme:
foos.Select(o => new Bar().InjectFrom(o));
vous pouvez également utiliser ValueInjecter pour mapper à partir d' objets anonymes et dynamiques
différences:
automapper créer une configuration pour chaque possibilité de mappage CreateMap ()
injecteur de valeur injecte depuis n'importe quel objet vers n'importe quel objet (il y a aussi des cas où vous injectez de l'objet vers le type de valeur)
automapper a l'aplatissement construit, et uniquement pour les types simples ou du même type, et il n'a pas d'aplatissement
valueinjecter seulement si vous en avez besoin vous faites target.InjectFrom<FlatLoopValueInjection>(source); also <UnflatLoopValueInjection>
et si vous voulez partir Foo.Bar.Name of type Stringpour FooBarName of type Class1vous héritez FlatLoopValueInjection et spécifiez cette
automapper mappe des propriétés avec le même nom par défaut et pour le reste, vous devez spécifier une par une, et faire des choses comme Prop1.Ignore (), Prop2.Ignore () etc.
valueinjecter a une injection par défaut .InjectFrom () qui fait les propriétés avec le même nom et le même type; pour tout le reste, vous créez vos injections de valeur personnalisées avec des logiques / règles de mappage individuelles, plus comme des aspects, par exemple de tous les accessoires de Type Foo à tous les accessoires de type Bar
Pour le dieu de l'amour, dites-moi que ValueInjector peut prendre un graphique profond ViewModel et mapper vers / à partir d'une entité commerciale de graphique profond et mapper tout ce qui est exactement le même sans travail, et que je dois seulement spécifier comment gérer ce qui est différent. J'espérais qu'AutoMapper ajouterait cette capacité mais elle ne s'est jamais matérialisée et je n'ai pas eu le temps d'écrire mon propre mappeur automatique.
Chris Marisic
3
@Chris Marisic vous pouvez l'utiliser pour le faire, au cas où vous voulez dire un clonage en profondeur, j'ai fait une injection une fois que cela le fait récursivement mais ne fonctionne pas pour les propriétés des collections valueinjecter.codeplex.com/Thread/View.aspx?ThreadId=236126 , ou vous pouvez faire un Flat ViewModel et utiliser l'aplatissement et le non-aplatissement, ce serait facile
Omu
Le ViewModel et les entités de domaine seraient similaires mais différents, donc pas un pur clone. 90% des propriétés sont généralement de type et de nom exacts, les ViewModels se retrouvent souvent avec des SelectLists et des éléments qui leur sont liés que je voudrais ignorer en revenant au domaine. Les deux sont très susceptibles d'avoir des collections d'objets dessus.
Chris Marisic du
27
<pedant>Ça a l'air cool, mais ça devrait peut-être être ValueInjectOr? </pedant>
Craig Stuntz
1
mais pour une raison quelconque, c'est euh :)
Omu
59
Comme je n'ai jamais utilisé aucun des autres outils, je ne peux parler que d'AutoMapper. J'avais quelques objectifs en tête pour créer AutoMapper:
Prise en charge de l'aplatissement des objets DTO stupides
Prise en charge de scénarios évidents prêts à l'emploi (collections, énumérations, etc.)
Être capable de vérifier facilement les mappages dans un test
Autorisez les cas limites pour résoudre les valeurs d'autres endroits (mappage de type personnalisé> type, mappage de membre individuel et certains cas de bord vraiment fous).
Si vous voulez faire ces choses, AutoMapper fonctionne très bien pour vous. Les choses que AutoMapper ne fait pas bien sont:
Remplissage d'objets existants
Non aplatissant
La raison étant que je n'ai jamais eu besoin de faire ces choses. Pour la plupart, nos entités n'ont pas de setters, n'exposent pas de collections, etc. c'est pourquoi il n'y en a pas. Nous utilisons AutoMapper pour aplatir en DTO et mapper à partir de modèles d'interface utilisateur pour commander des messages et similaires. C'est là que cela fonctionne vraiment très bien pour nous.
Comment puis-je découpler mon code de ValueInjecter? Pour moi, il semble qu'il y ait toujours une dépendance à ValueInjecter, c'est-à-dire dans mon projet Web, car j'utilise ValueInjecter (méthode d'extension) sur l'objet donné DIRECTEMENT.
Rookian
1
@Rookian, honnêtement, ce n'est pas une préoccupation à laquelle vous devriez réfléchir trop. Vous pouvez dépendre de l'interface comme @Omu mentionnée, donc si vous changez de mappeur, vous pourriez économiser du travail (probablement pas beaucoup). Ce type de dépendance est tout simplement trop difficile à résumer à moins que vous ne vouliez entrer dans un AOP complet qui est malheureusement souvent annulable, car .NET n'aide pas à fournir correctement le support AOP. Vous pouvez maintenant supprimer AOP une partie du mappage, surtout si vous utilisez MVC et écrivez des filtres d'action qui gèrent le mappage ViewModel / DomainModel.
Chris Marisic
13
pourquoi un emballage est-il la meilleure solution? La seule chose que vous devez faire si vous voulez changer de mappeur est d'implémenter la InjectFrom()méthode d'extension par vous-même.
jgauffin
1
J'ai également essayé les deux et je préfère AutoMapper. Je l'ai utilisé pour une petite partie de mon système où je mappe des entités avec des classes générées par Linq2Sql. Le mappage simple comme StockTotalQuantity -> stock_size_quantity ou UserId -> user_id fonctionnait avec AutoMapper par défaut. Cela n'a pas fonctionné avec ValeInjecter même après l'ajout de la convection. Rester sur AutoMapper pour l'instant.
Artur Kędzior
27
C'est une question que j'ai également recherchée, et pour mon cas d'utilisation, il semble que l'injecteur de valeur soit de loin. Il ne nécessite aucune configuration préalable à utiliser (peut affecter les performances, je suppose, bien que s'il est intelligemment mis en œuvre, il puisse mettre en cache les mappages pour les invocations futures plutôt que de les refléter à chaque fois), vous n'avez donc pas besoin de prédéfinir les mappages avant de les utiliser.
Mais surtout, il permet une cartographie inversée. Maintenant, je manque peut-être quelque chose ici car Jimmy mentionne qu'il ne voit aucun cas d'utilisation là où c'est nécessaire, alors peut-être que le modèle est incorrect, mais mon cas d'utilisation est que je crée un objet ViewModel à partir de mon ORM. Je l'affiche ensuite sur ma page Web. Une fois que l'utilisateur a terminé, je récupère le ViewModel en tant que httppost, comment cela est-il reconverti aux classes ORM d'origine? J'adorerais connaître le modèle avec automapper. Avec ValueInjector, c'est trivial, et il sera même aplati. ex: création d'une nouvelle entité
Le modèle créé par l'entitéframework (modèle d'abord):
À mon avis, cela ne devient pas beaucoup plus simple que cela?
(Donc, cela soulève la question, qu'est-ce qui ne va pas avec le modèle que je rencontre (et il semble que beaucoup d'autres le fassent), que ce n'est pas considéré comme ayant une valeur pour AutoMapper?)
Cependant, si ce modèle, tel que décrit, est celui que vous souhaitez utiliser, alors mon vote est injecteur de valeur par un mile du pays.
vous devriez probablement aussi poser cette question dans une question distincte étiquetée avec asp.net-mvc et les meilleures pratiques, ViewModel ..., atm Je ne vois aucun problème tant que cela fonctionne bien pour vous, mais je suis sûr que quelqu'un pourrait avoir des opinions différentes
Omu
Bien avoir appris plus de mvc. Je peux maintenant répondre à ma question. La façon de mettre à jour le modèle d'origine lorsque vous récupérez un modèle de vue peuplé consiste à utiliser la fonction UpdateModel () fournie par mvc.
DanH
1
UpdateModel () est utilisé pour remplir le modèle qui représente la vue, et est identique à l'action (modèle MyModelClasss)
Omu
Certes, mais si vous souhaitez avoir un modèle de vue distinct pour, par exemple, un modèle de référentiel, il peut être utilisé pour indiquer que le mappage est trivial (et il l'est souvent). Bien sûr, si ValueInjector plus complexe prend tout son sens.
DanH
1
Je pense que l'argument pourrait être avancé selon lequel vous ne devriez pas simplement redéfinir vos propriétés sur votre modèle de domaine - vous devriez utiliser des méthodes qui lui donnent un sens.
Réponses:
en tant que créateur de ValueInjecter , je peux vous dire que je l'ai fait parce que je voulais quelque chose de simple et de très flexible
Je n'aime vraiment pas écrire beaucoup ou écrire beaucoup
monkey code
comme:ValueInjecter est quelque chose comme mozilla avec ses plugins, vous créez ValueInjections et les utilisez
il y a des injections intégrées pour aplatir, aplatir et certaines sont destinées à être héritées
et cela fonctionne plus dans un type d'aspect , vous n'avez pas besoin de spécifier toutes les propriétés 1 à 1, au lieu de cela, vous faites quelque chose comme:
prendre toutes les propriétés int de la source dont le nom se termine par "Id", transformer la valeur et définir chacune une propriété dans l'objet source avec le même nom sans le suffixe Id et son type est hérité d'Entity, des trucs comme ça
donc une différence évidente, ValueInjecter est utilisé même dans les formulaires Windows avec aplatissement et aplatissement, c'est à quel point il est flexible
(mappage de l'objet aux contrôles de formulaire et inversement)
Automapper, non utilisable dans les formulaires Windows, pas de non-aplatissement, mais il a de bonnes choses comme le mappage de collections, donc si vous en avez besoin avec ValueInjecter, vous faites juste quelque chose comme:
foos.Select(o => new Bar().InjectFrom(o));
vous pouvez également utiliser ValueInjecter pour mapper à partir d' objets anonymes et dynamiques
différences:
automapper créer une configuration pour chaque possibilité de mappage CreateMap ()
injecteur de valeur injecte depuis n'importe quel objet vers n'importe quel objet (il y a aussi des cas où vous injectez de l'objet vers le type de valeur)
automapper a l'aplatissement construit, et uniquement pour les types simples ou du même type, et il n'a pas d'aplatissement
valueinjecter seulement si vous en avez besoin vous faites
target.InjectFrom<FlatLoopValueInjection>(source); also <UnflatLoopValueInjection>
et si vous voulez partirFoo.Bar.Name of type String
pourFooBarName of type Class1
vous héritez FlatLoopValueInjection et spécifiez cetteautomapper mappe des propriétés avec le même nom par défaut et pour le reste, vous devez spécifier une par une, et faire des choses comme Prop1.Ignore (), Prop2.Ignore () etc.
valueinjecter a une injection par défaut .InjectFrom () qui fait les propriétés avec le même nom et le même type; pour tout le reste, vous créez vos injections de valeur personnalisées avec des logiques / règles de mappage individuelles, plus comme des aspects, par exemple de tous les accessoires de Type Foo à tous les accessoires de type Bar
la source
<pedant>
Ça a l'air cool, mais ça devrait peut-être être ValueInjectOr?</pedant>
Comme je n'ai jamais utilisé aucun des autres outils, je ne peux parler que d'AutoMapper. J'avais quelques objectifs en tête pour créer AutoMapper:
Si vous voulez faire ces choses, AutoMapper fonctionne très bien pour vous. Les choses que AutoMapper ne fait pas bien sont:
La raison étant que je n'ai jamais eu besoin de faire ces choses. Pour la plupart, nos entités n'ont pas de setters, n'exposent pas de collections, etc. c'est pourquoi il n'y en a pas. Nous utilisons AutoMapper pour aplatir en DTO et mapper à partir de modèles d'interface utilisateur pour commander des messages et similaires. C'est là que cela fonctionne vraiment très bien pour nous.
la source
J'ai essayé les deux et préfère ValueInjecter car c'est si simple:
C'est tout ce qu'il faut savoir pour la grande majorité de mes besoins en injection. Cela ne peut pas être plus simple et élégant que cela.
la source
this object
méthode d'extension là-bas?InjectFrom()
méthode d'extension par vous-même.C'est une question que j'ai également recherchée, et pour mon cas d'utilisation, il semble que l'injecteur de valeur soit de loin. Il ne nécessite aucune configuration préalable à utiliser (peut affecter les performances, je suppose, bien que s'il est intelligemment mis en œuvre, il puisse mettre en cache les mappages pour les invocations futures plutôt que de les refléter à chaque fois), vous n'avez donc pas besoin de prédéfinir les mappages avant de les utiliser.
Mais surtout, il permet une cartographie inversée. Maintenant, je manque peut-être quelque chose ici car Jimmy mentionne qu'il ne voit aucun cas d'utilisation là où c'est nécessaire, alors peut-être que le modèle est incorrect, mais mon cas d'utilisation est que je crée un objet ViewModel à partir de mon ORM. Je l'affiche ensuite sur ma page Web. Une fois que l'utilisateur a terminé, je récupère le ViewModel en tant que httppost, comment cela est-il reconverti aux classes ORM d'origine? J'adorerais connaître le modèle avec automapper. Avec ValueInjector, c'est trivial, et il sera même aplati. ex: création d'une nouvelle entité
Le modèle créé par l'entitéframework (modèle d'abord):
Le ViewModel (que je peux décorer avec des validateurs):
Le ViewController:
À mon avis, cela ne devient pas beaucoup plus simple que cela?
(Donc, cela soulève la question, qu'est-ce qui ne va pas avec le modèle que je rencontre (et il semble que beaucoup d'autres le fassent), que ce n'est pas considéré comme ayant une valeur pour AutoMapper?)
Cependant, si ce modèle, tel que décrit, est celui que vous souhaitez utiliser, alors mon vote est injecteur de valeur par un mile du pays.
la source