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 -~----------~----~----~----~------~----~------~--~---
