Enterprise Library 5.0 With Prism 4.0

Topics: Enterprise Library Core, Exception Handling Application Block, Logging Application Block
Sep 15, 2012 at 12:54 AM
Edited Sep 15, 2012 at 12:54 AM

Hello,

I am trying to use EL 5.0 with prism.

As part of the bootstrapper process - I create the Logger Facade adapter- which uses following code for logging...

var logwriter = EnterpriseLibraryContainer.Current.GetInstance<LogWriter>();     

  logwriter.Write(message, category.ToString(), (int)priority);

 

While the bootstrapper is in process some amount of logging is done by the framework.. and starts writing on to a file...

 

as part of the ConfigureContainer() , I register the EnterpriseLibraryContainer to use my unity container.

   var configurator = new UnityContainerConfigurator(Container);            // Read the configuration files and set up the container.         

  EnterpriseLibraryContainer.ConfigureContainer(configurator, ConfigurationSourceFactory.Create());            

at this stage - any subsequent logging (through exception handling block) to the same logging Target Litener are getting written to a new file (increment file) because the earlier file is held by a different instance

Could any one please assist me in the same?

Sep 15, 2012 at 1:15 AM

I would recommend to dispose of the first LogWriter when you are done with it and are going to reconfigure the container.  This will release all of the locks on the Trace Listeners.  i.e. logwriter.Dispose();

--
Randy Levy
Enterprise Library support engineer
entlib.support@live.com 

Sep 17, 2012 at 4:56 PM

Tried this.. earlier as well.. does not work.. for some reason I am not able to get hold of the instance of the logger...

 

       var oldLogger = EnterpriseLibraryContainer.Current.GetInstance<LogWriter>();
            if (oldLogger != null) oldLogger.Dispose();

            var configurator = new UnityContainerConfigurator(Container);
            // Read the configuration files and set up the container.
            EnterpriseLibraryContainer.ConfigureContainer(configurator, ConfigurationSourceFactory.Create());

But if I dispose it right after writing the log message, it works (but I don't want to do that..). Please advice..

 

-Vikram

 

Sep 17, 2012 at 5:46 PM

If you are using an ILoggerFacade that uses the Service Locator to retrieve a LogWriter instance on every Log invocation then the current LogWriter should be returned (even if the UnityContainer was changed).  e.g.:

    public class EnterpriseLibraryLoggerAdapter : ILoggerFacade
    {
        private bool _disposed;

        #region ILoggerFacade Members

        public void Log(string message, Category category, Priority priority)
        {
            var logwriter = EnterpriseLibraryContainer.Current.GetInstance<LogWriter>();

            logwriter.Write(message, category.ToString(), (int)priority);
        }
    }

As long as the previous internal class that holds the lock is disposed then there shouldn't be any issue.

I'm not able to reproduce the issue so I must not be testing the same scenario; can you send a small sample project that recreates the issue?

--
Randy Levy
Enterprise Library support engineer
entlib.support@live.com 

Sep 17, 2012 at 7:49 PM

Thanks for the quick response... i'll get you a sample project soon..

but here is what I found -- (under ConfigureContainer()  of UnityBootstrapper)

      
    var oldLogger = EnterpriseLibraryContainer.Current.GetInstance<LogWriter>();
            if (oldLogger != null)
            {
                oldLogger.Write("same old logger.....", "Debug");
                oldLogger.Dispose();
            }
            var configurator = new UnityContainerConfigurator(Container);
            // Read the configuration files and set up the container.
            EnterpriseLibraryContainer.ConfigureContainer(configurator, ConfigurationSourceFactory.Create());
		//My unity container
            var newLogger = Container.Resolve<LogWriter>();
            newLogger.Write("did I work????? (yes it does)","Debug");
		//EnterpriseLibraryContainer
            var newLoggerAgain = EnterpriseLibraryContainer.Current.GetInstance<LogWriter>();
            newLoggerAgain.Write("But This gets a new logger","Debug");

 

basically I was under the impression that my EnterpriseLibraryContainer would use the same Continer once configured, but looks like now I have two different Containers? is that correct?

if yes then what is the most elegant way to deal with it in prism, as my Logger Facade is created much earlier than my servicelocator is configured (correct me if I am wrong) because of which I would have to use the EnterpriseLibraryContainer in the adapter

Sep 17, 2012 at 8:40 PM

found my solution, please let me know if there is a better way.. but this works fine for me...

all I did is, switched to configuring in the ConfigureServiceLocatr secion.. and I ensured I set the Container for the EnterpriseLibrary using the serviceLocator, and it works now....

here is my code...

 protected override void ConfigureServiceLocator()
        {
            base.ConfigureServiceLocator();
            var oldLogger = EnterpriseLibraryContainer.Current.GetInstance<LogWriter>();
            if (oldLogger != null)
            {
                oldLogger.Write("same old logger.....", "Debug");
                oldLogger.Dispose();
            }
            var configurator = new UnityContainerConfigurator(Container);
            // Read the configuration files and set up the container.
            EnterpriseLibraryContainer.ConfigureContainer(configurator, ConfigurationSourceFactory.Create());
            var newLogger = Container.Resolve<LogWriter>();
            newLogger.Write("did I work????? (yes it does)", "Debug");
            EnterpriseLibraryContainer.Current = ServiceLocator.Current;
            var newLoggerAgain = EnterpriseLibraryContainer.Current.GetInstance<LogWriter>();
            newLoggerAgain.Write("But this works now!!!!!!", "Debug");
        }

Sep 18, 2012 at 12:23 AM

I think that is a good solution.

--
Randy Levy
Enterprise Library support engineer
entlib.support@live.com