.NET преобразовать тип в подтип

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

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

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

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

Например:

У нас есть класс Инструмент

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);
            }
        }
    }

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

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


person Daniel Powell    schedule 10.05.2011    source источник


Ответы (1)


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

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

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

person DarkSquirrel42    schedule 10.05.2011