There is a bunch of people that say: "don't inject repositories in your
entities.."


2009/9/23 José F. Romaniello <[email protected]>

> 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