Как заставить AutoMapper работать с пользовательским соглашением об именах?

В проекте, над которым я работаю, мы сопоставляем автоматически сгенерированные DTO с бизнес-объектами. База данных имеет кхм необычное (но в основном согласованное) соглашение об именах, что означает, что можно преобразовать большинство имен свойств 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?


person Josh Kodroff    schedule 05.10.2010    source источник


Ответы (1)


Если все действительно непротиворечиво, как 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;
}
person Jab    schedule 05.10.2010
comment
Я не думаю, что это будет работать для того, что мне нужно. Я обновил вопрос, чтобы отразить, с каким именно соглашением об именах я работаю. Мне действительно нужна моя Func‹строка, строка›, чтобы сказать, какой элемент назначения исходит от какого исходного элемента. - person Josh Kodroff; 06.10.2010
comment
@Josh Kodroff проверьте обновленный ответ, я думаю, это то, что вам нужно. - person Jab; 06.10.2010
comment
Вот и все! Я просто не мог понять, где установить SourceMemberNameTransformer. Теперь я использую Mapper на нескольких уровнях (DTO, BO, VM), поэтому я не хочу использовать этот преобразователь повсеместно. Есть идеи, как сделать так, чтобы этого не произошло? - person Josh Kodroff; 06.10.2010
comment
Свойство SourceMemberNameTransformer было удалено после версии 2.1.1 Automapper. - person Kris-I; 17.08.2012