如何有效地设计创建/更新方法,这些方法需要创建/更新不同类型的属性
本文关键字:更新 创建 方法 属性 同类型 有效地 新方法 | 更新日期: 2023-09-27 18:25:53
我知道,这个问题很冗长,可能很难理解,但希望有人点击了它,我现在可以更详细地解释我的问题是什么。
我有一个Create方法,用于创建一个名为"opportunity"的对象。商机有许多不同的属性需要设置,但为了简单起见,我将使用"标题"、"位置"answers"开始日期"。
我还有一个Update方法,它可以做一些非常类似的事情,对于列出的属性,它将以相同的方式设置它们。然而,作为一个旁注,我需要两个单独的方法,因为它们确实不同。
这两种方法都将另一个名为"Entity"的对象作为参数,用于设置"opportunity"的值。
所以,现在是我的问题。我认为最好的方法是有一个方法来完成所有的属性设置,这两种方法都使用。我会向这个方法传递一个元组列表,其中包含1.)要设置的机会属性名称,以及2.)要将其设置为的实体属性值。然而,要做到这一点,我可能需要一个类似元组的字符串,对象作为实体属性值,可以是5种类型中的1种。据推测,这将导致拳击比赛(因此费用高昂)。除此之外,我将使用该类型来决定如何更新给定的机会属性,因此类似于:
if (PropType == typeof(string))
{
//Do something
}
else if (PropType == typeof(Picklist))
{
//Do something else
}
else if (PropType == typeof(DateTime))
{
//Do something else
}
我的问题是,这是一种有效的方法吗?对我来说,这背后的两个主要原因是,在create方法和update方法之间,以及在每个方法中,似乎都有很多重复的代码,比如if(entity.prop.value!=null)opp.op.value=entity.prop.value。第二个原因是这种方式更容易进行单元测试。我可以为要设置的每个机会属性创建一个测试,并将其作为元组列表传递到我的新方法中,如果它们已经正确创建/更新,则返回。
我考虑了一个KeyValuePairs列表,但我可能需要在列表中添加额外的信息,所以使用元组。此外,我认为元组传递到其他方法的成本较低(尽管分配更贵?)。
我确信,尽管我尽了最大努力,但这一点仍然不清楚,所以请提出任何问题。
编辑
为了更清楚地说明,有一个更新方法已经到位(尽管我正在考虑重写它),其中有很多相同的代码来设置这样的机会属性:
if(entity.Title.Value != null) opp.name = entity.Title.Value;
else throw new Exception("Title not specified");
if(entity.Town.Value != null) opp.town = entity.Town.Value;
else throw new Exception("Town not specified");
对所有字符串属性都执行此操作。我目前的观点是,我不认为我需要为所有的房产重复这一点,而是有这样的东西:
//newOpp is passed in as the new opportunity
//Fields refers to a tuple passed in as object, string
//Item1 = entity field value
//Item2 = newOpp property name
PropertyInfo[] OppProps = newOpp.GetType().GetProperties();
PropertyInfo prop;
foreach (var record in Fields)
{
prop = OppProps.FirstOrDefault(x => x.Name == record.Item2);
if(record.Item1 != null && prop != null)
{
Type PropType = prop.GetType();
if (PropType == typeof(string))
{
prop.SetValue(newOpp, record.Item1, null);
}
//Extend to include other types used e.g. DateTime etc.
}
}
因为代码只说了几行注释,所以我做了一个例子来说明我的意思。
public class Opportunity
{
public string Title { get; set; }
public string Location { get; set; }
public DateTime StartDate { get; set; }
}
public class OpportunityDto
{
public string Title { get; set; }
public string Location { get; set; }
[IgnoreMap]
public DateTime StartDate { get; set; }
}
public class Saver
{
public void CreateOpportunity(OpportunityDto dto)
{
var newOpportunity = new Opportunity();//You'll need some database logic here
MapProperties(dto, newOpportunity);
//Add save/create logic
}
public void UpdateOpportunity(OpportunityDto dto)
{
var existingUpportunity = new Opportunity();//you'll need some database query logic here
MapProperties(dto, existingUpportunity);
//Add save/update logic
}
public void MapProperties(OpportunityDto dto, Opportunity target)
{
Mapper.CreateMap<OpportunityDto, Opportunity>()
.ForAllMembers(opt => opt.Condition(srs => !srs.IsSourceValueNull));
Mapper.Map<OpportunityDto, Opportunity>(dto, target);
target.Startdate = dto.StartDate;//Insert more logic & mumbo jumbo here
//Or manually :
//target.Title = dto.Title;
//target.Location = dto.Location;
//target.StartDate = dto.StartDate;
}
}