Adding Support for ISupportInitialize in NHibernate
The .NET ISupportInitialize interface is used when we want to support staged initialization for objects. Its BeginInit method is called when initialization is about to start and EndInit when it is finished.
If we want, it is easy to add support for it in NHibernate. An option would be:
- BeginInit is called when the object is instantiated, like when NHibernate has loaded a record from the database and is about to hydrate the entity, and immediately after the Id property is set;
- EndInit is called after all properties are set.
We do this by using a custom interceptor, like we have in the past. We start by writing a class that inherits from EmptyInterceptor, and implements the listener interface for the PostLoad event, IPostLoadEventListener:
1: public sealed class SupportInitializeInterceptor : EmptyInterceptor, IPostLoadEventListener
2: {
3: private ISession session = null;
4:
5: public override void SetSession(ISession session)
6: {
7: this.session = session;
8: base.SetSession(session);
9: }
10:
11: public override Object Instantiate(String clazz, EntityMode entityMode, Object id)
12: {
13: var listeners = (this.session.SessionFactory as SessionFactoryImpl).EventListeners;
14: var metadata = this.session.SessionFactory.GetClassMetadata(clazz);
15: var proxy = metadata.Instantiate(id, entityMode);
16: var initializable = proxy as ISupportInitialize;
17:
18: if (initializable != null)
19: {
20: initializable.BeginInit();
21: }
22:
23: if (listeners.PostLoadEventListeners.OfType<SupportInitializeInterceptor>().Any() == false)
24: {
25: listeners.PostLoadEventListeners = listeners.PostLoadEventListeners.Concat(new IPostLoadEventListener[] { this }).ToArray();
26: }
27:
28: return (proxy);
29: }
30:
31: #region IPostLoadEventListener Members
32:
33: void IPostLoadEventListener.OnPostLoad(PostLoadEvent @event)
34: {
35: var initializable = @event.Entity as ISupportInitialize;
36:
37: if (initializable != null)
38: {
39: initializable.EndInit();
40: }
41: }
42:
43: #endregion
44: }
1: var sessionFactory = cfg.SetInterceptor(new SupportInitializeInterceptor()).BuildSessionFactory();