Oh, ok.. Your context wraper looks like a repository or dao.I don't remember
right now if there is an event for a get by id.

This case seems more suitable for dependency injection in entities:
http://fabiomaulo.blogspot.com/2008/11/entities-behavior-injection.html

You don't have to touch your entities (it will inject in your Context
property).


2009/9/23 Harm Neervens <[email protected]>

>
> I created an interface called IContextWrapper.
> My applications and business layers are only talking to that
> interface.
> the interface now looks like this (but will be extended :-))
>
> public interface IContextWrapper: IDisposable
>    {
>        string ConnectionString { get; set; }
>
>        T CreateObject<T>() where T : IEntity;
>        T GetObjectById<T>(object identity);
>        T GetObjectByKey<T>(string keyPropertyName, object keyValue);
>        T TryGetObjectById<T>(object identity);
>        T TryGetObjectByKey<T>(string keyPropertyName, object
> keyValue);
>        IList<T> GetObjectsByQuery<T>(string npathQuery);
>        IList<T> GetObjectsBySql<T>(string sql);
>
>        void DeleteObject(IEntity entity);
>        void Commit();
>        void CommitObject(IEntity entity);
>        void Clear();
>        bool ValidateBeforeCommit { get; set; }
>
>        bool IsDeleted(IEntity entity);
>        bool IsUpForCreation(IEntity entity);
>        bool IsDirty(IEntity entity);
>        bool IsClean(IEntity entity);
>
>        object GetObjectIdentity(IEntity entity);
>    }
>
> Now I have an implementation if IContextWrapper for each ORM
> (NHibernate, EF, NPersist etc)
> My Entities all implement IEntity and are derived form EntityBase:
>
> public interface IEntity
>    {
>        object ObjectIdentity { get; }
>        IContextWrapper ContextWrapper { get; set; }
>        bool IsDeleted { get; }
>        bool IsUpForCreation { get; }
>        bool IsDirty { get; }
>        bool IsClean { get; }
>    }
>
> public abstract class EntityBase: IEntity
>    {
>        protected IContextWrapper _ContextWrapper;
>
>        protected virtual object GetObjectIdentity()
>        {
>            return _ContextWrapper.GetObjectIdentity(this);
>        }
>
>        public object ObjectIdentity
>        {
>            get
>            {
>                return this.GetObjectIdentity();
>            }
>        }
>
>        public virtual IContextWrapper ContextWrapper
>        {
>            get
>            {
>                return _ContextWrapper;
>            }
>            set
>            {
>                _ContextWrapper = value;
>            }
>        }
>
>        public bool IsDeleted
>        {
>            get { return _ContextWrapper.IsDeleted(this); }
>        }
>
>        public bool IsUpForCreation
>        {
>            get { return _ContextWrapper.IsUpForCreation(this); }
>        }
>
>        public bool IsDirty
>        {
>            get { return _ContextWrapper.IsDirty(this); }
>        }
>
>        public bool IsClean
>        {
>            get { return _ContextWrapper.IsClean(this); }
>        }
>    }
>
> As you can see, when after an entity is instantiated I need to set the
> ContextWrapper property of the Entity, otherwise the whole system
> won't work.
> Now I do this by implementing ILoadEventListener. Here is my
> constructor for th NHibernate implementation of IContextWrapper:
>
> public ContextWrapper(string assemblyName, string connectionString)
>        {
>            _CacheInserted = new EntityCache(this);
>            _CacheDeleted = new EntityCache(this);
>
>            NHibernateHelper.AddAssembly(assemblyName);
>            NHibernateHelper.SetConnectionString(connectionString);
>
>            // TODO: investigate memory leaks and garbage collection
>            ILoadEventListener[] stack = new ILoadEventListener[]
> { new global::NHibernate.Event.Default.DefaultLoadEventListener(), new
> EntityLoadListener(this) };
>            NHibernateHelper.GetConfiguration
> ().EventListeners.LoadEventListeners = stack;
>
>            IPostLoadEventListener[] stack2 = new
> IPostLoadEventListener[] { new
> global::NHibernate.Event.Default.DefaultPostLoadEventListener(), new
> EntityPostLoadListener(this) };
>            NHibernateHelper.GetConfiguration
> ().EventListeners.PostLoadEventListeners = stack2;
>
>            _Session = NHibernateHelper.GetSessionFactory().OpenSession
> ();
>        }
>
> And here's the implementation of ILoadEventListener:
>
> public class EntityLoadListener : ILoadEventListener
>    {
>        IContextWrapper _ContextWrapper;
>
>        public EntityLoadListener(IContextWrapper contextWrapper)
>        {
>            _ContextWrapper = contextWrapper;
>        }
>
>        // this is the single method defined by the LoadEventListener
> interface
>        public void OnLoad(LoadEvent @event, LoadType loadType)
>        {
>            if (loadType.IsAllowProxyCreation)
>            {
>
>                ISessionImplementor source = @event.Session;
>
>                IEntityPersister persister =
> source.Factory.GetEntityPersister(@event.EntityClassName);
>
>                EntityKey keyToLoad = new EntityKey(@event.EntityId,
> persister, source.EntityMode);
>
>                IPersistenceContext persistenceContext =
> @event.Session.PersistenceContext;
>
>                // look for a proxy
>                object proxy = persistenceContext.GetProxy(keyToLoad);
>
>                if (proxy is IEntity)
>                {
>                    (proxy as IEntity).ContextWrapper =
> _ContextWrapper;
>                }
>            }
>        }
>    }
>
> So as you can see, if a proxy is loaded, I can set the ContextWrapper
> of my Entity.
> But if I have not proxy, the event will not fire and I'm not able to
> set the ContextWrapper property.
> Maybe now you understand why I need proxies all the time.
>
> Harm.
>
> On Sep 23, 9:16 pm, José F. Romaniello <[email protected]> wrote:
> > Let's go back. You say that this code is in your base class, a base class
> > for what?
> > What kind of classes inherit from this base? repositories, entities,
> > services?
> >
> > 2009/9/23 Harm Neervens <[email protected]>
> >
> >
> >
> >
> >
> > > > Your design is somewhat flawed, maybe you'd like to revise it.
> >
> > > This is not my design, but just some code snippet to express what my
> > > intentions are.
> > > I'm not posting this question to get critics at my design, but to get
> > > a decent answer at my question.
> > > I'm always told that open source communities were so helpfull :-(
> >
> > > On Sep 23, 9:01 pm, "Francisco A. Lozano" <[email protected]> wrote:
> > > > If your base classes are coupled to nhibernate, so is any class that
> > > > derives from them.
> >
> > > > Your design is somewhat flawed, maybe you'd like to revise it.
> Getting
> > > > the session through proxies from inside the entities is not something
> > > > I would expect to see on a well-designed application :/
> > > > Francisco A. Lozano
> >
> > > > On Wed, Sep 23, 2009 at 20:20, Harm Neervens <[email protected]>
> > > wrote:
> >
> > > > > I want this because my entities are POCO, and bu that I mean real
> > > > > Persistance Ignorant.
> > > > > I have code in my entities that references ISessionFactory, I
> create a
> > > > > dependancy to the NHibernate framework, and that's not what I want.
> > > > > I'm building an abstraction layer between my domain model and the
> ORM.
> > > > > In that way we can change ORM framework whenever we want (just by
> > > > > adjusting some configuration settings).
> > > > > Some of our customers prefer NHibernate, other Entity Framework or
> > > > > NPersist.
> >
> > > > > When I always have proxies, then in my base class I can use code
> like:
> >
> > > > >            if (entity is INHibernateProxy)
> > > > >            {
> > > > >                (entity as
> > > > > INHibernateProxy).HibernateLazyInitializer.Session.Load<T>..... etc
> > > > >            }
> >
> > > > > and in case of NPersist:
> >
> > > > >            if (entity is IInterceptable)
> > > > >            {
> > > > >                (entity as
> > > > > IInterceptable).Context.GetObjectById<T>....etc
> > > > >            }
> >
> > > > > Harm.
> >
> > > > > Until now (I mean for almost 5 years) I used NPersist. This is an
> ORM
> > > > > developed by Mats Helander and Roger Alsing (
> www.puzzleframework.com).
> > > > > Because the development has stopped, and there's no active
> community,
> > > > > I started to look at NHibernate. Another reason is that more and
> more
> > > > > customers are asking for it.
> > > > > In Entity Framework 4, there will also be POCO support, so in the
> > > > > future my abstaction layer will also support EF.
> > > > > Maybe it's a bit clearer now to you why I always want proxies for
> my
> > > > > entities.
> >
> > > > > On Sep 23, 5:39 pm, José F. Romaniello <[email protected]>
> wrote:
> > > > >> > When I have no proxy, I cannot cast my object to IInterceptor
> and so
> > > I
> >
> > > > >> will never get to my session/context object within my entity.
> >
> > > > >> Well.. I have to much questions. Why do you need to do that?
> > > > >> Is not a good way to get the current session by far.
> >
> > > > >> Inject ISessionFactory and use GetCurrentSession().. is a normal
> > > approach.- Hide quoted text -
> >
> > > > - Show quoted text -- Hide quoted text -
> >
> > - Show quoted text -
> >
>

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"nhusers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/nhusers?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to