C# 使用AutoMapper映射到方法

C# 使用AutoMapper映射到方法,c#,asp.net-mvc-2,automapper,C#,Asp.net Mvc 2,Automapper,我正在用C构建一个ASP.NET MVC 2应用程序,并成功地使用Automapper在ViewModels和业务对象之间来回映射值 除了几个显式属性之外,我的业务对象还将字典包装为未显式定义的属性的总括。类似于: public class MyBusinessObject { public void SetExtraPropertyValue<T>(string key, T value) { // ... } public T Get

我正在用C构建一个ASP.NET MVC 2应用程序,并成功地使用Automapper在ViewModels和业务对象之间来回映射值

除了几个显式属性之外,我的业务对象还将字典包装为未显式定义的属性的总括。类似于:

public class MyBusinessObject {
    public void SetExtraPropertyValue<T>(string key, T value) { 
        // ...
      }
    public T GetExtraPropertyValue<T>(string key, T defaultValue) {
        // ...
      }
}
我要存储和检索的值需要使用

businessModelInstance.SetExtraPropertyValue("CustomProp", newVal);

我两个方向都有问题。 首先,当从MyBusinessObject转到MyViewModel时,我认为在我的自定义Automapper配置文件中应该很简单:

CreateMap<MyBusinessObject, MyViewModel>()
  .ForMember(dest => dest.CustomProp, 
             opt => opt.MapFrom(s => s.GetExtraPropertyValue("CustomProp", "")));
在自定义概要文件类的configure方法中:

CreateMap<MyViewModel, MyBusinessObject>()
            .ConvertUsing<ItemExtraPropertyConverter>();

我的猜测是GetExtraPropertyValue和SetExtraPropertyValue实现有问题。我进行了一个快速测试,您上面提供的映射工作正常。以下是我用于测试的实现:

public class MyBusinessObject
{
    private readonly Dictionary<string, object> extraProperties = new Dictionary<string, object>();

    public int Id { get; set; }
    public string Name { get; set; }

    public void SetExtraPropertyValue<T>(string key, T value)
    {
        extraProperties.Add(key, value);
    }
    public T GetExtraPropertyValue<T>(string key, T defaultValue)
    {
        if (extraProperties.ContainsKey(key))
        {
            return (T)extraProperties[key];
        }

        return defaultValue;
    }
}

感谢您抽出时间来查看。你说得对,这个简单的测试对我很有效。一定是我的代码中有什么愚蠢的东西-我可以调试它。对我来说,更大的问题是如何将视图模型上的其他方向映射属性映射到业务对象上适当的字典条目。我仍然无法想出一个解决方案…有什么想法吗?我认为定制类型转换器可以解决这个问题。对视图模型的所有公共属性进行一点查询。使用属性名称作为调用SetPropertyValue的键。请注意,反射确实会对性能产生影响-您必须确定它是否是一个可接受的影响。这不是一个高容量站点,而是一个管理站点,因此反射不是问题。谢谢你给我指明了正确的方向。
public class ItemExtraPropertyConverter : ITypeConverter<MyViewModel, MyBusinessObject>
{
    public MyBusinessObject Convert(ResolutionContext context)
    {
        var destination = context.DestinationValue as MyBusinessObject;
        if (destination == null )
            throw new InvalidOperationException("Destination type is not of type MyBusinessObject");

        foreach (var property in context.SourceType.GetProperties())
            foreach (var attribute in property.GetCustomAttributes(true).OfType<ExtraPropertyAttribute>())
            {
                var key = attribute.Key;
                if (string.IsNullOrEmpty(key))
                    key = property.Name;
                destination.SetExtraPropertyValue(key, property.GetValue(context.SourceValue, null));
            }

        return destination;
    }
}

public class ExtraPropertyAttribute : Attribute
{
    public ExtraPropertyAttribute()
    {
    }
    public ExtraPropertyAttribute(string key)
    {
        Key = key;
    }

    public string Key { get; set; }
}

public class MyViewModel
{
    [ExtraProperty]
    public string CustomProp { get; set; }

    [ExtraProperty("OtherPropertyValue")]
    public string CustomProp2 { get; set; }
}
CreateMap<MyViewModel, MyBusinessObject>()
            .ConvertUsing<ItemExtraPropertyConverter>();
public class MyBusinessObject
{
    private readonly Dictionary<string, object> extraProperties = new Dictionary<string, object>();

    public int Id { get; set; }
    public string Name { get; set; }

    public void SetExtraPropertyValue<T>(string key, T value)
    {
        extraProperties.Add(key, value);
    }
    public T GetExtraPropertyValue<T>(string key, T defaultValue)
    {
        if (extraProperties.ContainsKey(key))
        {
            return (T)extraProperties[key];
        }

        return defaultValue;
    }
}