Problem with CustomTraceListener

Jan 31, 2009 at 2:27 PM
Hi. I created my own TraceListener. It works fine but I cannot add it using Enterprice Library Configuration Editor(ELCE): I create Custom Trace Listener using ELCE and trying to specify its type using 'Type' field. Then I point to the assembly that contains my listener implementation, but ELCE says that it cannot find type that inherits CustomTraceListener. But if I manually add my listener (to configuration file) it works fine. I found the source of this problem. If I add [ConfigurationElementType(typeof(CustomTraceListenerData))] attribute to my listener class then it can be added using ELCE. But if I replace CustomTraceListenerData with some class derived from it, ELCE don't see listener in the assembly. Here is the source code:
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  [ConfigurationElementType(typeof(LogTraceListenerData))]
  public class LogTraceListener : CustomTraceListener
  {
    public override void TraceData(TraceEventCache eventCache, string source, TraceEventType eventType,
      int id, object data)
    {
      if(data is LogEntry && this.Formatter != null && this.LogForm != null)
      {
        LogEntry entry = (LogEntry)data;
        string message = this.Formatter.Format(data as LogEntry);
        this.LogForm.AddRecord(message, entry.Severity);
      }
      else
      {
        this.WriteLine(data.ToString());
      }
    }
    
    public override void Write(string message)
    {
      if(this.LogForm != null)
      {
        this.LogForm.AddRecord(message, TraceEventType.Error);
      }
    }

    public override void WriteLine(string message)
    {
      this.Write(message + "\n");
    }
    
    public ILogForm LogForm { get; set; }

    protected override string[] GetSupportedAttributes()
    {
      return new string[1] { "LogForm" };
    }
  }

  [Assembler(typeof(LogTraceListenerAssembler))]
  public class LogTraceListenerData : CustomTraceListenerData
  {
    private const string m_LogFormProperty = "LogForm";

    [ConfigurationProperty(m_LogFormProperty, IsRequired = true)]
    public ILogForm LogForm { get; set; }
  }

  public class LogTraceListenerAssembler : CustomTraceListenerAssembler
  {
    public override TraceListener Assemble(IBuilderContext context, TraceListenerData objectConfiguration,
      IConfigurationSource configurationSource, ConfigurationReflectionCache reflectionCache)
    {
      LogTraceListenerData castedObjectConfiguration = (LogTraceListenerData)objectConfiguration;
      LogTraceListener result = new LogTraceListener();
      result.LogForm = castedObjectConfiguration.LogForm;
      return result;
    }
  }
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
What is the problem with this implementation?

And another question. How can I add my listener to ELCE 'New' menu, i. e. I want to extend  ELCE  that way it will show my listener in add 'New' listener  menu...

Best regards
Paul.


Feb 2, 2009 at 3:45 AM
Hi,

It is because that the Type loader in the ELCE is looking for a class that has [ConfigurationElementType(typeof(CustomTraceListenerData))] and inherits from CustomTraceListener.


Valiant Dudan
Global Technology and Solutions
Avanade, Inc.
entlib.support@avanade.com

Feb 2, 2009 at 8:43 AM
So, as I understand, I cannot add my own customizer for this listener. But what is the sense of such behaviour? And can I extend ELCE  that way it will show my listener
in add 'New' listener munu?
Feb 2, 2009 at 9:42 AM
I believe this is a bug since it works if you add the type manually in the configuration file.  I'll look into the issue tracker, see if it's already been logged before, and if not, I'll add one. 
"And can I extend ELCE  that way it will show my listener in add 'New' listener munu?" - Are you asking if you can have a design-time support for custom trace listener?  The Application Block Software Factory  in the version 3.x of EntLib allows you to do this.  Here's a screencast to get you started if you're interested.. http://www.codeplex.com/entlib/Wiki/View.aspx?title=Videos

Additional thread link: http://www.codeplex.com/entlib/Thread/View.aspx?ThreadId=13593


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

Feb 2, 2009 at 9:44 AM
Thank you!
Feb 2, 2009 at 10:21 AM
While searching for an entry in the issue tracker, found this one - http://www.codeplex.com/entlib/WorkItem/View.aspx?WorkItemId=12857.  Not exactly pertaining to custom trace listeners but I think the concept is the same.  Looks like it's an expected behavior.


Sarah Urmeneta
Global Technology & Solutions
Avanade, Inc.
entlib.support@avanade.com
Feb 2, 2009 at 10:42 AM
I didn't understand why it's expected behavior... If you mean the problems that are described in "Avoiding configuration pitfalls with incomatible copies
of Enterprise Library" article so I solved these problems some time ago...
Feb 2, 2009 at 10:54 AM
No, not exactly that one. "When you supply a customized configuration object you need to provide design-time support for the new configuration object." - comment by fsimonazzi.
I believe he was referring to the adding of a new node class that is mapped to your new configuration object as mentioned in the other link I included above.(ThreadId=13593)


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