I'm generating an interface to concrete implementation copier. A later step will be to determine if I can easily add varying behaviors depending on the copy type requested (straight copy, or try, or try-catch-addToValidationDictionary). This is the main one I need/am working on is the try-catch-addToValidationDictionary. It would be lovely if the copy statements themselves(result.AssetTag = asset.AssetTag
) were reusable in list form for another consumer that doesn't need the try/catch/validation functionality.
The General form is this:
public static AssetService
{
public static ModelAsset CreateAssetDomain(IAmAnAsset asset, IValidationDictionary validationDictionary)
{
var result=new ModelAsset();
var hasExceptions=false;
try
{
result.AssetTag = asset.AssetTag;
}
catch (System.Exception exception)
{
validationDictionary.AddError(Member.Name<IAmAnAsset>(lIAmAnAsset => lIAmAnAsset.AssetTag), exception.Message);
hasExceptions = true;
}
try
{
result.LocationIdentifer = asset.LocationIdentifer;
}
catch (System.Exception exception)
{
validationDictionary.AddError(Member.Name<IAmAnAsset>(lIAmAnAsset => lIAmAnAsset.LocationIdentifer), exception.Message);
hasExceptions = true;
}
...
if (hasExceptions)
throw new ArgumentException("Failed validation");
return result;
}
}
I'm trying to factor out some of the repetition with lambdas but the Member.Name<IAmAnAsset>(lIAmAnAsset => lIAmAnAsset.AssetTag)
from this post seems to only take an Expression<Func<T,object>>
and I'm not sure how you would make use of the Expression> overload.
One attempt was as follows:
Action<Action, Expression<Func<IAmAnAsset, object>>> CopyActions = (copyAction, expression) =>
{
try
{
copyAction();
}
catch (Exception exception)
{
validationDictionary.AddError(Member.Name<IAmAnAsset>(expression), exception.Message);
hasExceptions = true;
}
};
var copyActions = new Dictionary<string,Action>()
{
Member.Name<IAmAnAsset>(z=>z.AddedBy),()=>result.AddedBy=asset.AddedBy},
Member.Name<IAmAnAsset>(z=>z.AssetTag),()=>result.AssetTag=asset.AssetTag},
...
}
foreach (var item in copyActions)
{
tryCopyAction(item.Value, item.Key);
}
if (hasExceptions)
throw new ArgumentException("Failed validation");
return result;
I'm hoping for a solution that reduces the duplication inherent in
Member.Name<IAmAnAsset>(z=>z.AddedBy),()=>result.AddedBy=asset.AddedBy},
on any of the following criteria:
- needing the IAmAnAsset.AddedBy in 2 places on each line
- needing .AddedBy 3 times on the same line
Member.Name<IAmAnAsset>
on each and every line- Is it possible to have this Expression utilized to retrieve either the string name, or the value of evaluating it?