Свободный NHibernate: применение атрибута ко всем элементам свойства, сопоставленным через Компонент - PullRequest
2 голосов
/ 10 августа 2011

Я использую Fluent NHibernate (1.2) и работаю над реализацией шифрования на уровне столбцов.У меня есть пользовательский тип, который обрабатывает шифрование, так что модель домена может иметь собственные типы данных в виде открытого текста (простые строки, целые числа, DateTimes и т. Д.), И вся работа по шифрованию / дешифрованию выполняется за кулисами.хотел бы указать, какие свойства в каждой модели домена шифровать с помощью атрибута, и использовать соглашение, чтобы указать пользовательский тип для этих свойств, чтобы модели домена представляли собой удобные POCO без упоминания пользовательского типа:

public class EncryptedAttribute : Attribute {}

public class UserRecord {
  public virtual Guid Id { get; set; }
  public virtual string Username { get; set; }
  [Encrypted]
  public virtual string EmailAddress { get; set; }
  [Encrypted]
  public virtual DateTime DateOfBirth { get; set; }
  [Encrypted]
  public virtual PersonName LegalName { get; set; }
  // etc.
}

public class PersonName {
  public virtual string Given { get; set; }
  public virtual string Middle { get; set; }
  public virtual string Family { get; set; }
}

public class EncryptedColumnConvention
  : AttributePropertyConvention<EncryptedAttribute> {
  protected override void Apply(
    EncryptedAttribute attribute, IPropertyInstance instance)
  {
    var dbType = typeof(EncryptedColumnType<>).MakeGenericType(domainType);
    instance.CustomType(dbType);  
  }
}

public class UserRecordMap : ClassMap<UserRecord> {
  public UserRecordMap() {
    Id(o => o.Id);
    Map(o => o.Username);
    Map(o => o.EmailAddress);
    Map(o => o.DateOfBirth);
    Component(o => o.LegalName).ColumnPrefix("LegalName");
    // etc.
  }
}

public class PersonNameMap : ComponentMap<PersonName> // etc.

Как показано выше, я пытаюсь связать все это вместе с AttributePropertyConvention.Это хорошо работает для простых свойств, например, EmailAddress получит пользовательский тип EncryptedColumnType.

Но он не работает для свойств, которые являются сложными типами (например, LegalName), которые сопоставлены через Компоненты.Я хочу зашифровать каждое свойство LegalName, потому что я украсил его [Зашифровано].Другими словами, я хочу, чтобы таблица базы данных UserRecord имела три зашифрованных поля имени - имя, отчество и семейство.

Кажется, что AttributePropertyConvention просто не применяется вообще к LegalName или любому из егосвойства участника.Возможно, мне нужно использовать другой тип конвенции для рассмотрения этого случая?

Я знаю, что могу просто декорировать отдельные свойства в PersonName с помощью [Encrypted], вместо того, чтобы декорировать свойство [LegalName] в UserRecord.Я проверил это, и он отлично работает.Я могу прибегнуть к этому подходу, если это необходимо, но мне интересно попытаться использовать приведенный выше подход к работе.

1 Ответ

0 голосов
/ 06 марта 2012

После этого я не нашел способа напрямую реализовать то, что я описал.Я мог видеть, как трудно или невозможно реализовать такую ​​вещь, основываясь на том, как работают атрибуты в C #.

Вместо этого я просто добавил атрибут [Encrypted] к каждому свойству класса PersonName и позволилPersonName столбцы в результирующей таблице базы данных всегда будут зашифрованы.В будущем, если мне понадобится отобразить PersonName как незашифрованный «компонент» другого объекта, возможно, я мог бы украсить незашифрованный класс атрибутом, который отключает шифрование для всех егосопоставленные столбцы / компоненты, переопределяющие любые атрибуты [Encrypted], найденные в сопоставлениях свойств / компонентов этого класса.

...