Реализация IDataErrorInfo с использованием Castle.DynamicProxy в сценарии отложенной загрузки с использованием NHibernate - PullRequest
2 голосов
/ 24 декабря 2010

Я реализовал интерфейс IDataErrorInfo, используя Castle.DynamicProxy IIterceptor.Я также реализовал перехватчик NHibernate, который создает мои объекты с помощью этого перехватчика.Проблема с лениво загруженными объектами.Они создаются с использованием класса фабрики прокси, указанного в файле конфигурации nhibernate, который, очевидно, не обеспечивает реализацию IDataErrorInfo.Эти прокси маскируют основную реализацию IDataErrorInfo моим перехватчиком, что приводит к сбою проверки.

Каковы возможные решения этой проблемы?

(Один из способов решения этой проблемы -изменить фабрику прокси по умолчанию, которую использует nhibernate.)

1 Ответ

0 голосов
/ 27 декабря 2010

Одним из решений является переопределение фабрики прокси Castle по умолчанию и расширение массива интерфейсов с IDataErrorInfo. LazyInitializer фактически не реализует этот интерфейс, он только перенаправляет вызовы к нашей собственной прокси-реализации. DataBindingProxyFactory должен быть зарегистрирован как прокси-фабрика NHibernate.

 public class DataBindingProxyFactory : ProxyFactory, IProxyFactoryFactory
  {
    public IProxyValidator ProxyValidator { get { return new DynProxyTypeValidator(); } }

    public IProxyFactory BuildProxyFactory()
    {
      return new DataBindingProxyFactory();
    }

    public bool IsInstrumented(Type entityClass)
    {
      return true;
    }

    public override INHibernateProxy GetProxy(object id, ISessionImplementor session)
    {
      try
      {
        var initializer = new LazyInitializer(EntityName, PersistentClass, id, GetIdentifierMethod,
          SetIdentifierMethod, ComponentIdType, session);

        var interfaces =
          new List<Type>(Interfaces){
            typeof (INotifyPropertyChanged),
            typeof (IDataErrorInfo)
          }.ToArray();

        var generatedProxy = IsClassProxy
          ? DefaultProxyGenerator.CreateClassProxy(PersistentClass, interfaces, initializer)
          : DefaultProxyGenerator.CreateInterfaceProxyWithoutTarget(Interfaces[0], interfaces,
            initializer);

        initializer._constructed = true;
        return (INHibernateProxy) generatedProxy;
      }
      catch (Exception e)
      {
        log.Error("Creating a proxy instance failed", e);
        throw new HibernateException("Creating a proxy instance failed", e);
      }
    }
  }
...