1

I wanna write a Generic AutoMapper's Resolver for changing Model's file path.
Without Generic Resolver, I've written the following resolver :
e.g:

public class UserPhotoPathResolver : ValueResolver<User, string>
{
    protected override string ResolveCore(User source)
    {
        var url = new UrlHelper(HttpContext.Current.Request.RequestContext);
        return url.Content(string.IsNullOrWhiteSpace(source.PhotoPath) 
            ? StaticVariables.DefaultUserImagePath 
            : source.PhotoPath);
    }
}

Now, I've written the following Resolver :

public class FilePathResolver<T, TProperty> : ValueResolver<T, string> where T : class
{
    private readonly Expression<Func<T, TProperty>> _propertyExpression;

    public FilePathResolver(Expression<Func<T, TProperty>> propertyExpression)
    {
        _propertyExpression = propertyExpression;
    }

    protected override string ResolveCore(T source)
    {
        Type typeOfEntity = typeof(T);

        MemberExpression member = _propertyExpression.Body as MemberExpression;
        if (member == null)
            throw new ArgumentException(string.Format("Expression '{0}' refers to a method, not a property.", _propertyExpression));

        PropertyInfo propInfo = member.Member as PropertyInfo;
        if (propInfo == null)
            throw new ArgumentException(string.Format("Expression '{0}' refers to a field, not a property.", _propertyExpression));

        if (typeOfEntity != propInfo.ReflectedType && !typeOfEntity.IsSubclassOf(propInfo.ReflectedType))
            throw new ArgumentException(string.Format("Expresion '{0}' refers to a property that is not from type {1}.", _propertyExpression, typeOfEntity));

        string filePath = Convert.ToString(ModelHelpers.GetStringPropertyValue(source, propInfo.Name));
        return string.IsNullOrWhiteSpace(filePath)
            ? string.Empty
            : UrlHelpers.GetUrlHelperInstance().Content(filePath);
    }
}

public static object GetStringPropertyValue(object src, string propertyName)
{
    return src.GetType().GetProperty(propertyName).GetValue(src, null);
}

public static TProperty GetValue<T, TProperty>(T obj, Expression<Func<T, TProperty>> expression) where T : class
{
    if (obj == null) return default(TProperty);
    Func<T, TProperty> func = expression.Compile();
    return func(obj);
}

But FilePathResolver returns this string MyApp.Classes.Helpers.FilePathResolver%602[MyApp.DAL.ModelName,System.String]

I'm using this resolver as the following :

Mapper.CreateMap<EntityClass, EntityClassModel>()
    .ForMember(m => m.ResolvedLogoPath, opt => opt.ResolveUsing(m => new FilePathResolver<EntityClass, string>(p => p.LogoPath)));

How can I do it?

2
  • Please post ModelHelpers.GetStringPropertyValue content. Looks like the problem is somewhere in its implementation. Commented Nov 5, 2013 at 22:04
  • @k0stya It's written at the of Middle Code Box Commented Nov 6, 2013 at 6:47

1 Answer 1

1

The problem is that wrong ResolveUsing method overload is used.

enter image description here

But you need the following one.

enter image description here

You can fix it by changing mapping configuration in the following way.

Mapper.CreateMap<EntityClass, EntityClassModel>()
    .ForMember(m => m.ResolvedLogoPath, 
        opt => opt.ResolveUsing<FilePathResolver<EntityClass, string>>()
        .ConstructedBy(() => new FilePathResolver<EntityClass, string>(p => p.LogoPath)));

Or even like this:

Mapper.CreateMap<EntityClass, EntityClassModel>()
  .ForMember(m => m.ResolvedLogoPath, 
    opt => opt.ResolveUsing(new FilePathResolver<EntityClass, string>(p => p.LogoPath)));
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.