I'm creating some attributes to use on properties, that are part of types manipulated by an extension method I created.
the method ChargeFrom
assign the value of an object to another, mapping the same properties names and types, so if I have two classes like:
class Book
{
public int Id {get; set;}
public string Title {get; set;}
public decimal Price {get; set;}
}
class BookViewModel
{
public int Id {get; set;}
public string Title {get; set;}
public decimal Price {get; set;}
}
when I have an object of type Book
:
var book = new Book{Id=1, Title = "T1", Price = 345};
I can instansiate a BookViewModel Like this :
var bookModel = new BookViewModel();
bookModel.ChargeFrom(book);
I use reflection in this method. but the method itself is not why I ask the question. in the library I have two attributes : SourcePropertyAttribute
which is used to specify explicitly a different property name on the source object. and DeepChargingAttribute
which loop through a property if it's a custom type (if the user decided so!) and set its value from the corresponding property on the source object (ex: AuthorViewModel
in BookViewModel
, corresponds to Author
property in Book
class). I'm new in Attributes programming, though it shows no different, except on taking such decision. my problem is that sometimes a property may have both attributes: DeepChargingAttribute
and SourcePropertyAttribute
, or only one of them.
I don't know if the nested if is the key solution for that case, and if so, what is the most efficient way doing it?
here's my code:
static void ChargeProperties(object target, object source)
{
PropertyInfo[] targetProperties = target.GetType().GetProperties();
PropertyInfo[] sourceProperties = source.GetType().GetProperties();
foreach (PropertyInfo propTarget in targetProperties)
{
foreach (PropertyInfo propSource in sourceProperties)
{
if (propTarget.Name == propSource.Name && propTarget.PropertyType == propSource.PropertyType)
{
propTarget.SetValue(target, propSource.GetValue(source));
}
}
if (Attribute.IsDefined(propTarget, typeof(SourcePropertyAttribute)))
{
//there's three cases:
//1 - the property has only SourcePropertyAttribute
//2 - the property has only DeepChargingAttribute
//3 - the property has both attributes
//so what is efficient way to know it while iterating overy every property?!
var sourcePropAttr = (SourcePropertyAttribute)Attribute.GetCustomAttribute(propTarget, typeof(SourcePropertyAttribute));
var sp = sourceProperties.SingleOrDefault(x => x.Name == sourcePropAttr.PropertyName);
if (sp == null)
{
if (sourcePropAttr.AlwaysOnSource)
throw new NullReferenceException($"The property name '{sourcePropAttr.PropertyName}' couldn't be found on the source object.") { Source = "Mshwf.Charger" };
else
continue;
}
propTarget.SetValue(target, sp.GetValue(source));
}
}
}
Aucun commentaire:
Enregistrer un commentaire