我知道,问题是冗长的,可能很难理解,但希望有人点击它,我现在可以更详细地解释我的问题。
我有一个Create方法,用于创建一个名为'opportunity'的对象。机会有许多不同的属性需要设置,但为了简单起见,我将使用'Title','Location'和'StartDate'。
我还有一个Update方法,它做了非常相似的事情,并且就列出的属性而言,它将以相同的方式设置它们。但是,作为旁注,我需要两种不同的方法,因为它们确实不同。
两种方法都将另一个称为“实体”的对象作为参数,用于设置“机会”的值。
所以,现在我的问题。我认为最好的方法是使用1个方法来完成所有属性设置,这两种方法都使用。我会将一个元组列表传递给这个方法,该方法包含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.prop .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.
}
}
答案 0 :(得分:0)
因为代码说了更多的注释行,我举了一个例子来说明我的意思。
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;
}
}