MISE À JOUR: ce genre de choses a évolué dans un beau projet, voir à http://valueinjecter.codeplex.com Convention Simple Automapper pour la cartographie à deux voies (entités à/de ViewModels)
vérifier, je viens d'écrire un automapper simple, il prend la valeur de la propriété avec le même nom et type d'un objet et le met dans un autre, et vous pouvez ajouter des exceptions (ifs, commutateur) pour chaque type que vous pourriez avoir besoin
alors dites-moi ce que vous en pensez il ?
je l'ai fait pour que je puisse faire quelque chose comme ceci:
Product –> ProductDTO
ProductDTO –> Product
qui est la façon dont il a commencé:
J'utilise le type « objet » dans mes entrées/Dto/ViewModels pour Dropdowns parce que je envoyer au html IEnumerable <SelectListItem> et je reçois un tableau de chaînes de clés sélectionnées Retour
public void Map(object a, object b)
{
var pp = a.GetType().GetProperties();
foreach (var pa in pp)
{
var value = pa.GetValue(a, null);
// property with the same name in b
var pb = b.GetType().GetProperty(pa.Name);
if (pb == null)
{
//no such property in b
continue;
}
if (pa.PropertyType == pb.PropertyType)
{
pb.SetValue(b, value, null);
}
}
}
UPDATE: le véritable usage:
les méthodes de génération (entrée = Dto):
public static TI BuildInput<TI, T>(this T entity) where TI: class, new()
{
var input = new TI();
input = Map(entity, input) as TI;
return input;
}
public static T BuildEntity<T, TI, TR>(this TI input)
where T : class, new()
where TR : IBaseAdvanceService<T>
{
var id = (long)input.GetType().GetProperty("Id").GetValue(input, null);
var entity = LocatorConfigurator.Resolve<TR>().Get(id) ?? new T();
entity = Map(input, entity) as T;
return entity;
}
public static TI RebuildInput<T, TI, TR>(this TI input)
where T: class, new()
where TR : IBaseAdvanceService<T>
where TI : class, new()
{
return input.BuildEntity<T, TI, TR>().BuildInput<TI, T>();
}
dans le contrôleur:
public ActionResult Create()
{
return View(new Organisation().BuildInput<OrganisationInput, Organisation>());
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create(OrganisationInput o)
{
if (!ModelState.IsValid)
{
return View(o.RebuildInput<Organisation,OrganisationInput, IOrganisationService>());
}
organisationService.SaveOrUpdate(o.BuildEntity<Organisation, OrganisationInput, IOrganisationService>());
return RedirectToAction("Index");
}
La vraie méthode Carte
public static object Map(object a, object b)
{
var lookups = GetLookups();
var propertyInfos = a.GetType().GetProperties();
foreach (var pa in propertyInfos)
{
var value = pa.GetValue(a, null);
// property with the same name in b
var pb = b.GetType().GetProperty(pa.Name);
if (pb == null)
{
continue;
}
if (pa.PropertyType == pb.PropertyType)
{
pb.SetValue(b, value, null);
}
else if (lookups.Contains(pa.Name) && pa.PropertyType == typeof(LookupItem))
{
pb.SetValue(b, (pa.GetValue(a, null) as LookupItem).GetSelectList(pa.Name), null);
}
else if (lookups.Contains(pa.Name) && pa.PropertyType == typeof(object))
{
pb.SetValue(b, pa.GetValue(a, null).ReadSelectItemValue(), null);
}
else if (pa.PropertyType == typeof(long) && pb.PropertyType == typeof(Organisation))
{
pb.SetValue(b, pa.GetValue<long>(a).ReadOrganisationId(), null);
}
else if (pa.PropertyType == typeof(Organisation) && pb.PropertyType == typeof(long))
{
pb.SetValue(b, pa.GetValue<Organisation>(a).Id, null);
}
}
return b;
}
hors sujet - j'adore votre première ligne à la 'question': "check this out ..."! haha. J'ai pensé à faire cela mais pas eu les boules –
@cottsak oui c'est vraiment bonne ouverture: D, jamais vu un comme ça – Omu
@ChuckNorris - Pouvez-vous s'il vous plaît préciser pourquoi Automapper (initialement) n'était pas recommandé pour ViewModel <-> mappage de modèle ? Je me rends compte que c'est un commentaire très en retard dans cette discussion et beaucoup de choses pourraient avoir avancé dans Automapper et ValueInjector, mais néanmoins, si vous avez un point remarquable sur pourquoi éviter Automapper, s'il vous plaît laissez-nous savoir. – Faredoon