Как заставить AutoMapper работать с пользовательским соглашением об именах? - PullRequest
5 голосов
/ 05 октября 2010

В проекте, над которым я работаю, мы сопоставляем автоматически генерируемые DTO с бизнес-объектами. База данных имеет ahem необычное (но в значительной степени непротиворечивое) соглашение об именах, что означает, что можно преобразовать большинство имен свойств DTO в их эквивалентные имена свойств бизнес-объекта, тем самым сохраняя много строк кода.

Например, в DTO (и базе данных) у нас есть свойство с именем account_ID__created, которое сопоставляется со свойством BO с именем CreatedAccountId. Такое преобразование происходит в MemberNameTransformer.GetBoMemberName(), поэтому оно не так просто, как немного другое соглашение с другим разделителем.

Исходя из того, что у меня есть в исходном коде AutoMapper, я предпочитаю следующее:

public class DtoBoMappingOptions : IMappingOptions
{
    public INamingConvention SourceMemberNamingConvention
    {
        get { return new PascalCaseNamingConvention(); }
        set { throw new NotImplementedException(); }
    }

    public INamingConvention DestinationMemberNamingConvention
    {
        get { return new PascalCaseNamingConvention(); }
        set { throw new NotImplementedException(); }
    }

    public Func<string, string> SourceMemberNameTransformer
    {
        get { return s => s; }
        set { throw new NotImplementedException(); }
    }

    public Func<string, string> DestinationMemberNameTransformer
    {
        get { return MemberNameTransformer.GetBoMemberName; }
        set { throw new NotImplementedException(); }
    }
}

Теперь, как мне указать Mapper использовать эти параметры при сопоставлении SomeDto с SomeBusinessClass? Я понимаю, что у меня может быть неправильный интерфейс в IMappingOptions. Реальное мясо того, чего я пытаюсь достичь, находится в MemeberNameTransformer.GetBoMemberName().

Дополнительный кредит: Как я могу указать Mapper использовать эти параметры при сопоставлении любого IDto с IBusinessObject?

1 Ответ

8 голосов
/ 06 октября 2010

Если все действительно непротиворечиво, например textFirstName, вы можете использовать некоторые встроенные функции.

Mapper.Initialize(cfg => cfg.RecognizePrefixes(new[] { "text" }));

В противном случае вам нужно написать собственный класс INamingConvention, который будет выглядеть примерно так ..

class DTONaming : INamingConvention
{

    #region INamingConvention Members

    public string SeparatorCharacter
    {
        get { return string.Empty; }
    }

    public Regex SplittingExpression
    {
        get { return new Regex(""); }
    }

    #endregion
}

Затем вы можете зарегистрировать это в automapper.

Mapper.Initialize(cfg => cfg.SourceMemberNamingConvention = new DTONaming());

И AutoMapper будет использовать это для любых сопоставлений, поэтому, если вам нужно ограничить регистрацию этих префиксов или пользовательских объектов именованиявам может потребоваться инициализировать и повторно инициализировать его или что-то.Я сомневаюсь, что схема именования будет иметь последствия.

Редактировать

С вашими недавними добавлениями вы будете использовать SourceMemberNameTransformer вместо этого.Это позволяет вам написать функцию, которая конвертирует имена самостоятельно.

Mapper.Initialize(cfg => cfg.SourceMemberNameTransformer = ConvertNames);
private static string ConvertNames(string inputString)
{
    var sections = inputString.Split('_');
    // transform the sections into w/e you need
    return inputString;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...