Skip to content

Instantly share code, notes, and snippets.

@Martin-Andersen
Created December 16, 2013 17:06
Show Gist options
  • Save Martin-Andersen/7990457 to your computer and use it in GitHub Desktop.
Save Martin-Andersen/7990457 to your computer and use it in GitHub Desktop.
If you want to use NHibernate lazy load and also want to implements INotifyPropertyChanged on your entities the you need this code. The code is taken from this article http://weblogs.asp.net/ricardoperes/archive/2012/06/19/implementing-an-interceptor-using-nhibernate-s-built-in-dynamic-proxy-generator.aspx
FluentConfiguration cfg = Fluently.Configure()
.Database(MsSqlConfiguration.MsSql2008.IsolationLevel(IsolationLevel.ReadCommitted).ConnectionString(connectionString)
/*.ShowSql()*/)
.Mappings(m => m.FluentMappings.AddFromAssemblyOf<SagMap>()
//.ExportTo("c:\\temp")
.Conventions.Add(typeof (NHibernateConvention))
.Conventions.Add(DefaultLazy.Always()))
.Cache(c => c.ProviderClass<SysCacheProvider>().UseSecondLevelCache())
.ExposeConfiguration(ExtendConfiguration);
private void ExtendConfiguration(Configuration config)
{
config.SetInterceptor(new NotifyPropertyChangedInterceptor());
//config.SetListener(ListenerType.Load, new CacheLoadEventListener(new WorkflowBusinessCache()));
config.FilterDefinitions[SkemaVersionFilter.NAME] = new SkemaVersionFilter();
if (_opretDatabaseSkema)
{
try
{
// This NHibernate tool takes a configuration (with mapping info in)
// and exports a database schema from it
new SchemaExport(config).Drop(false, true);
new SchemaExport(config).Create(false, true);
}
catch (Exception ex)
{
_log.Error("NHibernate BuildSkema fejlede", ex);
throw;
}
}
}
[Serializable]
public class ModelBase
{
public virtual long Id { get; set; }
......................
[PropertyCopy(false)]
[field: NonSerialized]
public virtual event PropertyChangedEventHandler PropertyChanged;
[PropertyCopy(false)]
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged(string propertyName)
{
var handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
}
using System;
using System.ComponentModel;
using NHibernate;
using NHibernate.Proxy.DynamicProxy;
using IInterceptor = NHibernate.Proxy.DynamicProxy.IInterceptor;
//weblogs.asp.net/ricardoperes/archive/2012/06/19/implementing-an-interceptor-using-nhibernate-s-built-in-dynamic-proxy-generator.aspx
namespace Lbf.Driftstoette.Domain.NHibernate
{
public class NotifyPropertyChangedInterceptor : EmptyInterceptor
{
private static readonly ProxyFactory _factory = new ProxyFactory();
private ISession _session;
public override void SetSession(ISession session)
{
_session = session;
base.SetSession(session);
}
public override object Instantiate(string clazz, EntityMode entityMode, object id)
{
Type entityType = Type.GetType(clazz);
var proxy = _factory.CreateProxy(entityType, new PrivateNotifyPropertyChangedInterceptor(), typeof (INotifyPropertyChanged)) as IProxy;
if (proxy != null)
{
var interceptor = proxy.Interceptor as PrivateNotifyPropertyChangedInterceptor;
if (interceptor != null)
interceptor.Proxy = _session.SessionFactory.GetClassMetadata(entityType).Instantiate(id, entityMode);
}
_session.SessionFactory.GetClassMetadata(entityType).SetIdentifier(proxy, id, entityMode);
return (proxy);
}
private class PrivateNotifyPropertyChangedInterceptor : IInterceptor
{
private PropertyChangedEventHandler _changed = delegate { };
public Object Proxy { get; set; }
#region IInterceptor Members
public Object Intercept(InvocationInfo info)
{
Boolean isSetter = info.TargetMethod.Name.StartsWith("set_");
Object result = null;
if (info.TargetMethod.Name == "add_PropertyChanged")
{
var propertyChangedEventHandler = info.Arguments[0] as PropertyChangedEventHandler;
_changed += propertyChangedEventHandler;
}
else if (info.TargetMethod.Name == "remove_PropertyChanged")
{
var propertyChangedEventHandler = info.Arguments[0] as PropertyChangedEventHandler;
_changed -= propertyChangedEventHandler;
}
else
{
result = info.TargetMethod.Invoke(Proxy, info.Arguments);
}
if (isSetter)
{
String propertyName = info.TargetMethod.Name.Substring("set_".Length);
_changed(info.Target, new PropertyChangedEventArgs(propertyName));
}
return (result);
}
#endregion
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment