Omu*_*Omu 2 c# mapping asp.net-mvc automapping automapper
更新:这个东西已经演变成一个很好的项目,请访问http://valueinjecter.codeplex.com
那么告诉我你怎么看?
我这样做了所以我可以这样做:
Product –> ProductDTO
ProductDTO –> Product
Run Code Online (Sandbox Code Playgroud)
它是如何开始的:
我在我的Inputs/Dto/ViewModels for DropDowns中使用"object"类型,因为我向html发送了一个IEnumerable <SelectListItem>并且我收到了一个选定键的字符串数组
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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
更新:
实际用法:
Build方法(Input = 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>();
}
Run Code Online (Sandbox Code Playgroud)
在控制器中:
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");
}
Run Code Online (Sandbox Code Playgroud)
真正的Map方法
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;
}
Run Code Online (Sandbox Code Playgroud)
只需使用AutoMapper.这很好,但它会成长为一个迷你项目.
只有一些事情AM(真正的)做的是:
但它肯定是一个有趣的空间,而自动映射的想法肯定是有用的.
有点像DI在15或33行与NInject或其朋友 - 酷,但为什么?
我认为你已经阅读了关于Jimmy博客上双向映射的文章和评论?
您可能想要添加的一件事是缓存反射位.如果您将对象映射两次,则可能不希望再次查找所有反射内容.此外,像GetValue和SetValue这样的东西很慢,我切换到后期委托+ Reflection.Emit以加快速度.
| 归档时间: |
|
| 查看次数: |
3757 次 |
| 最近记录: |