gpt4 book ai didi

c# - 用于双向映射的简单约定自动映射器(实体到/来自 ViewModel)

转载 作者:行者123 更新时间:2023-11-30 18:53:16 25 4
gpt4 key购买 nike

更新:这个东西已经发展成为一个不错的项目,请在 http://valueinjecter.codeplex.com 查看它


检查一下,我刚刚写了一个简单的自动映射器,它从一个对象的同名和同类型的属性中获取值,并将其放入另一个对象中,您可以为您可能需要的每种类型添加异常(ifs、switch)< br/>

那么请告诉我您对此有何看法?

我这样做是为了可以做这样的事情:

Product –> ProductDTO

ProductDTO –> Product

事情就是这样开始的:

我在 Inputs/Dto/ViewModels 中为 DropDown 使用“object”类型,因为我向 html 发送了一个 IEnumerable 并且我收到了一个由选定键组成的字符串数组返回

 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);
}

}
}

更新:实际用法:
构建方法(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>();
}

在 Controller 中:

    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");
}

真正的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;
}

最佳答案

只需使用 AutoMapper .这很好,但它会成长为一个小型项目。

AM(真正的)所做的一些事情是:

  • 报告您是否有无法映射到的属性
  • 展平物体
  • 为您提供钩子(Hook)来自定义某些方面,而不是在一个大的 switch 语句中
  • 出于性能原因而非直接反射而使用 Expression.Compile

但这肯定是一个有趣的空间,而且自动映射的想法当然很有用。

有点像15中的DI或 33 lines vs NInject 或其 friend - 很酷,但为什么呢?

我认为您已经阅读了 article and comments regarding 2 way mapping on Jimmy's blog

关于c# - 用于双向映射的简单约定自动映射器(实体到/来自 ViewModel),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1781707/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com