.NET конвертировать тип в подтип - PullRequest
0 голосов
/ 10 мая 2011

Мы используем NHibernate в нашем проекте и подключаемся к событиям перед обновлением / вставкой / удалением, чтобы провести некоторый аудит.

Мы хотим проверять каждую сущность в своей собственной таблице аудита, которая имеет ту же схему, что и исходная таблица (возможно, с помощью операции аудита, такой как «Обновление», «Вставка» и т. Д.).

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

Чтобы сделать это просто, я решил, что могу просто расширить существующие классы домена и затем определить новое отображение Nhibernate для этих расширенных классов.

Например:

У нас есть класс Instrument

public class Instrument : BaseObject, IAuditable
    {
        public virtual string Title { get; set; }

        public virtual IList<Control> Controls { get; set; }

        public virtual CouncilRegion Region { get; set; }

        public Type GetAuditType()
        {
            return typeof (InstrumentAudit);
        }

Я определил интерфейс Iauditable, чтобы мы могли выяснить, какой класс является классом аудита для любого объекта Iauditable.

Аудиторский класс выглядит следующим образом

public class InstrumentAudit : Instrument
{}

У него нет дополнительной функциональности, это просто хак, который позволяет нам сопоставить его с нашей таблицей аудита в NHibernate.

Похоже, это сработает, но проблема возникает при попытке обработать события NHibernate

public class EventListener: IPreInsertEventListener, IPreUpdateEventListener, IPreDeleteEventListener
{
    private readonly IAuditLogger _logger = new AuditLogger();

    public bool OnPreInsert(PreInsertEvent e)
    {
        Audit(e.Entity as BaseObject, AuditType.Insert);
        return false;
    }
}
 private void Audit(object entity, AuditType auditType)
        {
            if(entity is IAuditable && entity is BaseObject)
            {
                _logger.Log(entity, auditType);
            }
        }

e.Entity дано мне как объект.

 public class AuditLogger : IAuditLogger
    {
        public void Log(object entity, AuditType auditType)
        {
            if (entity is IAuditable && entity is BaseObject)
            {
                var auditObject = entity as IAuditable;

                Type type = auditObject.GetAuditType();

                var x = (type) auditObject;

                DataRepository.Instance.Save(x);
            }
        }
    }

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

К сожалению, не похоже, что вы можете приводить к переменной, это должен быть фактический тип, есть ли в любом случае это так, чтобы я мог приводить или преобразовывать объект в его тип "аудита", не прибегая к конструкторам / конвертерам для каждого типа аудита, который принимает свой базовый тип и сохраняет свойства?

1 Ответ

0 голосов
/ 10 мая 2011

хорошо, простой ответ, вы не можете, если ваш audObject не является экземпляром InstrumentAudit или подклассом

просто потому, что между классами Instrument и InstrumentAudit нет никаких дополнительных полей или методов, это не означает, что вы легко можете привести из Instrument к InstrumentAudit, потому что Instrument не является подклассом InstrumentAudit

если вам нужен способ клонирования ваших объектов без реализации конвертеров x, посмотрите деревья выражений look @: вы можете установить словарь функций, проиндексированных соответствующими типами аудита, который хранит функции «клонирования» ... если вы найти функцию клона для нужного типа в dict, использовать ее ... если нет, создать функцию с использованием деревьев выражений и сохранить ее для дальнейшего использования

...