السيارات البسيطة للسيارات لرسم الخرائط في اتجاهين (كيانات/من ViewModels)
-
21-09-2019 - |
سؤال
تحديث: تطورت هذه الأشياء إلى مشروع جميل ، شاهدها في http://valueinjecter.codeplex.com
تحقق من ذلك ، لقد كتبت للتو سيارة بسيطة ، وتستغرق القيمة من الخاصية بنفس الاسم ونوع كائن واحد وتضعه في آخر ، ويمكنك إضافة استثناءات (IFS ، التبديل) لكل نوع قد تحتاجه
لذا قل لي ما رأيك في ذلك؟
لقد فعلت ذلك حتى أتمكن من فعل شيء مثل هذا:
Product –> ProductDTO
ProductDTO –> Product
هكذا بدأ:
أستخدم نوع "الكائن" في المدخلات/DTO/ViewModels للمنسدات لأنني أرسل إلى html a ienumerableu003CSelectListItem> وأتلقى مجموعة سلسلة من المفاتيح المحددة مرة أخرى
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);
}
}
}
تحديث:الاستخدام الحقيقي:
طرق البناء (الإدخال = 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>();
}
في وحدة التحكم:
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");
}
طريقة الخريطة الحقيقية
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;
}
المحلول
شيء واحد قد ترغب في إضافته هو تخزين بتات الانعكاس. إذا قمت بتخطيط كائن مرتين ، فربما لا ترغب في البحث عن جميع الأشياء المنعكسة مرة أخرى. أيضًا ، أشياء مثل GetValue و SetValue بطيئة جدًا ، لقد تحولت إلى المندوبين المتأخرين + Reflection.mit لتسريع الأمور.
نصائح أخرى
فقط استخدم السيارات. هذا جيد ، لكنه سوف ينمو ليصبح مشروعًا صغيرًا.
فقط بعض الأشياء (الحقيقية) هي:
- الإبلاغ إذا كان لديك خصائص لا يمكن تعيينها
- كائنات تسطيح
- توفير السنانير لك لتخصيص بعض الجوانب ، وليس في بيان التبديل الكبير
- باستخدام Expression.Compile لأسباب Perf بدلاً من التفكير مباشرة
لكن من المؤكد أنها مساحة مثيرة للاهتمام في الفوضى ، وفكرة رسم الخرائط التلقائية مفيدة بالتأكيد.
قليلا مثل دي في 15 أو 33 الخطوط مقابل Ninject أو أصدقائها - بارد ، ولكن لماذا؟.
أنا أعتبر أنك قرأت مقال وتعليقات بشأن رسم الخرائط على مدونة جيمي ?
مجرد فكرة:
قد يتساءل المرء عن الهدف من التجريد إذا تم تعيين التجريد بسهولة إلى تلك التي يتم استخلاصها.
يمكنك إضافة استثناءات (IFS ، التبديل) لكل نوع قد تحتاجه
أنت لن تفعل هذا. بجدية. عبارات الحالة التي تعمل على أنواع الكائنات هي نمط OOP سيء. أعني ، سيء حقًا. مثل القيادة مع مشروب من الفودكا داخل معدتك. قد ينجح الأمر لبعض الوقت ، ولكن في النهاية تواجه مشكلة.
حسنًا ، أخبرك جيمي بعدم استخدام السيارات ... لكنني أراهن أنه يعني شيئًا آخر. الآن ، هل اخترعت شيئًا مختلفًا - شيء يجعل جيمي سعيدًا؟ ؛-) لا ، لقد صنعت للتو سياراتك نصف مدفوعة. وأخبرك جيمي بعدم استخدامه! ؛-)
إذن هذا هو اقتراحي: تجاهل ما يقوله جيمي ، فقط فكر في نفسك .. واستخدم السيارات ؛-)