Print Page | Close Window

GlobalCache - EntityManagerProvider doesn't fire ManagerCreated

Printed From: IdeaBlade
Category: Cocktail
Forum Name: Community Forum
Forum Discription: A professional application framework using Caliburn.Micro and DevForce
URL: http://www.ideablade.com/forum/forum_posts.asp?TID=4091
Printed Date: 27-Apr-2025 at 6:26pm


Topic: GlobalCache - EntityManagerProvider doesn't fire ManagerCreated
Posted By: cefernan
Subject: GlobalCache - EntityManagerProvider doesn't fire ManagerCreated
Date Posted: 02-Apr-2013 at 12:55pm
Hi guys,

I've written a structure of global cache exactly like TempHire does. 

So, in the constructor of my GlobalCacheRepository:
entityManagerProvider.ManagerCreated += new EventHandler<EntityManagerCreatedEventArgs>(OnManagerCreated)
    .MakeWeak(eh => entityManagerProvider.ManagerCreated -= eh);
And:
internal void OnManagerCreated(object sender, EntityManagerCreatedEventArgs e)
{
    if (_globalCache == nullreturn;
 
    Seed(e.EntityManager);
 
    e.EntityManager.Cleared += new EventHandler<EntityManagerClearedEventArgs>(OnCleared)
        .MakeWeak(eh => e.EntityManager.Cleared -= eh);
}
internal void OnCleared(object sender, EntityManagerClearedEventArgs e)
{
    Seed(e.EntityManager);
}
private void Seed(EntityManager entityManager)
{
    var entities = _globalCache.Get<T>();
    entityManager.ImportEntities(entities, MergeStrategy.OverwriteChanges);
}
But, when I run the app I realize that the method  OnManagerCreated is never fired. Consequently, the ViewModel loads no results in my objects that read my global cache entities.

The method LoadAsync() in GlobalCache contains the cached entities that I need.

So, if I implement IDiscoverableViewModel in the same ViewModel and run the app through Harness, the global cache starts to work.

I think my mistake is something related to MEF.





Replies:
Posted By: mgood
Date Posted: 02-Apr-2013 at 1:43pm
That means the EntityManager has already been created at the time you install the OnManagerCreated handler. The EntityManager gets created the first time the Manager property of the EntityManagerProvider is accessed. Your application must be accessing the Manager property before you get a chance to install the handler. 

Make sure that each UnitOfWork actually gets a new instance of the EntityManagerProvider injected and that its Manager property is not accessed before each of the repositories is fully instantiated. 

To ensure that you get a new instance make sure you have attributed the entityManagerProvider parameter with the NonShared creation policy as it is done in TempHire.

[ImportingConstructor]
        public ResourceMgtUnitOfWork(
[Import(RequiredCreationPolicy = CreationPolicy.NonShared)] IEntityManagerProvider<TempHireEntities>
                entityManagerProvider,
[Import(AllowDefault = true)] IGlobalCache globalCache = null)
            : base(entityManagerProvider)
        {
...
        }


Posted By: mgood
Date Posted: 02-Apr-2013 at 1:49pm
Also, the TempHire Harness is not using the global cache. The Harness uses a single shared EntityManager instead. You will see that the GlobalCache class is not part of the Harness project, so it's not being found at runtime and in addition the Harness bootstrapper registers the EntityManagerProvider as a singleton.


Posted By: cefernan
Date Posted: 02-Apr-2013 at 2:30pm
Marcel, you are completely right!

I found my mistake. This line in the constructor of UnitOfWorkBase was the problem:
entityManagerProvider.Manager.VerifierEngine.PropertyNameToDisplayNameTranslator += PropertyNameToDisplayNameTranslator;
I was accessing the Manager before install the OnManagerCreated handler. I removed this line and now everything is perfect.

Thank you!!!

Now, I'll find a better place to translate the property names.



Posted By: mgood
Date Posted: 02-Apr-2013 at 3:08pm
You have a few options to safely configure the EntityManagers once they are created. 

1. You can subclass the EntityManagerProvider and override the CreateEntityManager method. 

2. You can handle the static EntityManager.EntityManagerCreated event.

3. Or you can do it in the EntityManagerProvider.ManagerCreated event just like how the repository is populating the cache. 


Posted By: cefernan
Date Posted: 02-Apr-2013 at 4:03pm
I chose the third option.

Thank you again.



Print Page | Close Window