ILoggingUpdateHandler documentation and samples

Topics: Logging Application Block
Sep 7, 2010 at 6:46 PM

Hi

I wanted a particular method to invoked when an entry in the configuration file changes. I am caching all the logging configuration data from a custom config file, and want the cache to refresh itself whenever the logging configuration section changes in the config file.

How can we do it in Entlib 5.0? In 4.1 I could simple do this via reflecting on the LogWriter class and adding a handler to the Configsource private member internal. Now in 5.0, LogWriter is implemented using LogwriterImpl and it doesn't have and configSource member internally that I can add a handler to. I also tried using the following code, but the handler doesn't invoke. Can someone point to some better documentation around updateCoordinator etc? Or an approach as how I should do whatever I am trying to implement.

//My implementation

 var writer = EntLibLogging.Logger.Writer;
LogUpdater updateDelegate = new LogUpdater(RefreshLogFilters);
var updateCoordinatorField = writer.GetType().GetField("updateCoordinator", BindingFlags.Instance | BindingFlags.NonPublic);
object updateCoordinator = updateCoordinatorField.GetValue(writer);
var eventSourcefield = updateCoordinator.GetType().GetField("eventSource", BindingFlags.Instance | BindingFlags.NonPublic);
object eventSource = eventSourcefield.GetValue(updateCoordinator);
var sectionChangeHandlerField = eventSource.GetType().GetField("sectionChangeHandlers", BindingFlags.Instance | BindingFlags.NonPublic);
var sectionChangeHandler = (EventHandlerList)sectionChangeHandlerField.GetValue(eventSource);
sectionChangeHandler.AddHandler(LoggingSettings.SectionName, updateDelegate);

 

Sep 8, 2010 at 3:48 AM

Hi saurabc,

Are you using your own modified and signed entlib 4.1 in the implementation you have pasted? I asked this because I was trying to find the "updateCoordinator" field and I believe it is not part of the original entlib 4.1 signed assemblies.

Anyway with regards to what you're trying to achieve, is using a FileDependency in your caching will work for you? Here's a related thread http://entlib.codeplex.com/Thread/View.aspx?ThreadId=64582 for your reference. Or you can also try if using .NET FileSystemWatcher class will be a good option for you too. HTH.

Gino Terrado
Global Technology and Solutions
Avanade, Inc.
entlib.support@avanade.com

 

 

Sep 8, 2010 at 1:42 PM
Gino

I am using Entlib 5.0. I have something like this working in 4.1 without the update co-ordinator, but I am not able to do the same in 5.0 because of the changes in the LogWriter implementation. What do you suggest?

Thanks
Saurabh


From: [email removed]
To: [email removed]
Date: Tue, 7 Sep 2010 20:48:19 -0700
Subject: Re: ILoggingUpdateHandler documentation and samples [entlib:226365]

From: AvanadeSupport
Hi saurabc,
Are you using your own modified and signed entlib 4.1 in the implementation you have pasted? I asked this because I was trying to find the "updateCoordinator" field and I believe it is not part of the original entlib 4.1 signed assemblies.
Anyway with regards to what you're trying to achieve, is using a FileDependency in your caching will work for you? Here's a related thread http://entlib.codeplex.com/Thread/View.aspx?ThreadId=64582 for your reference. Or you can also try if using .NET FileSystemWatcher class will be a good option for you too. HTH.
Gino Terrado
Global Technology and Solutions
Avanade, Inc.
entlib.support@avanade.com


Read the full discussion online.
To add a post to this discussion, reply to this email (entlib@discussions.codeplex.com)
To start a new discussion for this project, email entlib@discussions.codeplex.com
You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe on CodePlex.com.
Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at CodePlex.com
Sep 8, 2010 at 2:23 PM

You can subscribe to the SourceChanged event of an instance of IConfigurationSource.  This is the link to this topic from the documentation.

 

Sarah Urmeneta
Global Technology & Solutions
Avande, Inc.
entlib.support@avanade.com

Sep 8, 2010 at 4:02 PM

Sarah/Gino

 

I did try this yesterday, and even with completely correct code, my event handlers don't fire. What I could be doing wrong here?

 

class Program
    {
        static void Main(string[] args)
        {
            IConfigurationSource source = new FileConfigurationSource("external.config");
            source.SourceChanged += new EventHandler<ConfigurationSourceChangedEventArgs>(source_SourceChanged);
            source.AddSectionChangeHandler("loggingConfiguration", ConfigChangedEvent);
            Console.WriteLine("Hello World");
            Console.ReadLine();
            source.Dispose();
            Console.ReadLine();
        }

        static void source_SourceChanged(object sender, ConfigurationSourceChangedEventArgs e)
        {
            //throw new NotImplementedException();
            int i = 0;
            Console.WriteLine("This Changed -> {0}", e.ChangedSectionNames);
        }

        static void ConfigChangedEvent(Object sender, ConfigurationChangedEventArgs e)
        {
           Console.WriteLine("This Changed -> {0}", e.SectionName);
        }

    }

Sep 8, 2010 at 10:15 PM
saurabc wrote:

Sarah/Gino

 

I did try this yesterday, and even with completely correct code, my event handlers don't fire. What I could be doing wrong here?

 

class Program
    {
        static void Main(string[] args)
        {
            IConfigurationSource source = new FileConfigurationSource("external.config");
            source.SourceChanged += new EventHandler<ConfigurationSourceChangedEventArgs>(source_SourceChanged);
            source.AddSectionChangeHandler("loggingConfiguration", ConfigChangedEvent);
            Console.WriteLine("Hello World");
            Console.ReadLine();
            source.Dispose();
            Console.ReadLine();
        }

        static void source_SourceChanged(object sender, ConfigurationSourceChangedEventArgs e)
        {
            //throw new NotImplementedException();
            int i = 0;
            Console.WriteLine("This Changed -> {0}", e.ChangedSectionNames);
        }

        static void ConfigChangedEvent(Object sender, ConfigurationChangedEventArgs e)
        {
           Console.WriteLine("This Changed -> {0}", e.SectionName);
        }

    }

 Any advice? I am just stuck on this one.

Sep 9, 2010 at 12:41 AM

How did you make changes to the file?

 

Sarah Urmeneta
Global Technology & Solutions
Avande, Inc.
entlib.support@avanade.com

Sep 9, 2010 at 1:34 AM
AvanadeSupport wrote:

How did you make changes to the file?

 

Sarah Urmeneta
Global Technology & Solutions
Avande, Inc.
entlib.support@avanade.com

Manually updated the external configuration file, with the breakpoints set. They never got hit.

Sep 9, 2010 at 1:57 AM

I failed to notice before, I think you manually updated the external configuration file after the call to source.Dispose().  Remove that line and try it out.

 

Sarah Urmeneta
Global Technology & Solutions
Avande, Inc.
entlib.support@avanade.com

Sep 9, 2010 at 2:24 PM

It still doesn't work. I put in that Dispose() call just to ensure the GC wasn't cleaning the source object, as part of the compiler optimization. Just wanted a reference to be alive till the last line. Anyways, I removed the line, and it still didn't work.

Sep 10, 2010 at 3:22 AM

Ok, so the other possibility would be that you might be modifying the wrong file.  Are you modifying the external.config file from the output folder? The one from the bin\debug folder.

 

Sarah Urmeneta
Global Technology & Solutions
Avande, Inc.
entlib.support@avanade.com

Sep 10, 2010 at 2:32 PM

Yes, the file I am modifying is in the bin\Debug folder.

Sep 13, 2010 at 6:29 PM

Sarah/Gino

Any thoughts? I am really waiting on this.

Thanks

Saurabh

Sep 14, 2010 at 12:53 AM

I think the instance of IConfigurationSource got disposed since there was no longer any reference to it.  For the sake of testing, add this line before the Console.ReadLine and see what happens.

EnterpriseLibraryContainer.Current = EnterpriseLibraryContainer.CreateDefaultContainer(source);

You don't necessarily have to put this code especially if you don't want to replace the EnterpriseLibraryContainer.Current.  The point is just there should be something that references the IConfigurationSource object so it doesn't get disposed.

 

Sarah Urmeneta
Global Technology & Solutions
Avande, Inc.
entlib.support@avanade.com