I think the easiest way to solve this problem is to use the IMemberConfigurationExpression<DsMyDataSet.TMyRow>.Condition()
method and use a try-catch
block to check if accessing the source value throws a StrongTypingException
.
Here's what your code would end up looking like:
Mapper.CreateMap<DsMyDataSet.TMyRow, MyRowDto>()
.ForMember( target => target.PositionFolder,
options => options.Condition(source => {
try { return source.PositionFolder == source.PositionFolder; }
catch(StrongTypingException) { return false; }
});
If this is a common occurrence then you have a few other options to avoid writing all this code for each member.
One way is to use an extension method:
Mapper
.CreateMap<Row,RowDto>()
.ForMember( target => target.PositionFolder, options => options.IfSafeAgainst<Row,StrongTypingException>(source => source.PositionFolder) )
when the following is in the solution:
public static class AutoMapperSafeMemberAccessExtension
{
public static void IfSafeAgainst<T,TException>(this IMemberConfigurationExpression<T> options, Func<T,object> get)
where TException : Exception
{
return options.Condition(source => {
try { var value = get(source); return true; }
catch(TException) { return false; }
});
}
}
AutoMapper also has some built in extensibility points that could be leveraged here as well. A couple possibilities that jump out at me are:
Define a custom
IValueResolver
implementation. There is already a similar implementation in the solution that you could use: theNullReferenceExceptionSwallowingResolver
. You could probably copy that code and then just change the part that specifies what kind of exception you're working with. Documentation for configuration is on the AutoMapper wiki, but the configuration code would look something like:Mapper.CreateMap<Row,RowDto>() .ForMember( target => target.PositionFolder, options => options.ResolveUsing<ExceptionSwallowingValueResolver<StrongTypingException>>());