Click here to Skip to main content
15,991,544 members
Articles / Programming Languages / C#
Article

Plug-in Manager for Logging - Configure MSEL2 On the fly

Rate me:
Please Sign up or sign in to vote.
3.46/5 (5 votes)
20 Mar 20065 min read 27.7K   550   17   2
A plug-in Manager allow switching between different logging tools and 3rd parties (like log4net; nLog ; MSEL Logging Block and other).

Sample Image - Article.jpg

Introduction 

This is a simple plugin for logging actions and exception may happened in your application.
Also we will take a look how to configure MS Enterprise Library for .NET Framework 2.0 programatically.

Using the code

In this Article we have these technical points:

1-    What is a plug-in? and how to be implemented in out case (Logging Plugin Manager)?<o:p __designer:dtid="1407374883553308">

2-    What will be the benefits of implementing singleton pattern in our case?<o:p __designer:dtid="1407374883553315">

3-    How to load assemlies dynamically in a configurable way?<o:p __designer:dtid="1407374883553322">

4-    How to configure MSEL 2 Logging block on the fly without need for the pre-setting with MS configuraiton tool?<o:p __designer:dtid="1407374883553329">

<o:p __designer:dtid="1407374883553332">     

What is a plug-in? and how to be implemented in out case (Logging Plugin Manager)?<o:p __designer:dtid="1407374883553337">

.NET allows the dynamic loading of assemblies that is necessary for a good plug-in implementation.

Plug-in systems provide extensibility and flexibility. By using our Plug-in we will be able to attach more than implementation for many logging 3rd parties. And use the selector to select or activate one of them. <o:p __designer:dtid="1407374883553342">

<o:p __designer:dtid="1407374883553345">     

How to build a plug-in?<o:p __designer:dtid="1407374883553349">

This part contains a lot of old and well known information; but it is nice chance to refresh our knowledge. <o:p __designer:dtid="1407374883553352">

The first step in making the logging plug-in, after creating a solution workspace, is to create a common project LoggingManager.ExceptionsHandlerInterface. You'll use it to hold classes that will be accessed by both the plug-ins and the application that calls them. The object of doing this is to keep the dependencies down; there is little advantage in creating plug-ins if the application has to refer to the plug-in project to compile or run.<o:p __designer:dtid="1407374883553355">

<o:p __designer:dtid="1407374883553358">     

The interface used here is IExceptionsHandler. interface has a main method: Log() with 4 overloads:<o:p __designer:dtid="1407374883553361">

1- Simple logging with only choosing the target. <o:p __designer:dtid="1407374883553364">

bool Log(LogTarget oLogTarget, string LoggedString);<o:p __designer:dtid="1407374883553370">

<o:p __designer:dtid="1407374883553373">     

2- Logging with choosing the target and the severity level. <o:p __designer:dtid="1407374883553376">

bool Log(LogTarget oLogTarget, string LoggedString, LoggedDataLevel oLoggedDataLevel);<o:p __designer:dtid="1407374883553383">

<o:p __designer:dtid="1407374883553386">     

3- Logging with choosing the target and type for the logged info.<o:p __designer:dtid="1407374883553389">

bool Log(LogTarget oLogTarget, string LoggedString, LoggedDataType oLoggedDataType);<o:p __designer:dtid="1407374883553396">

<o:p __designer:dtid="1407374883553399">     

4- Logging with choosing the target and type for the logged info and everity.<o:p __designer:dtid="1407374883553402">

bool Log(LogTarget oLogTarget, string LoggedString, LoggedDataType oLoggedDataType, LoggedDataLevel oLoggedDataLevel);        <o:p __designer:dtid="1407374883553411">

<o:p __designer:dtid="1407374883553414">     

<o:p __designer:dtid="1407374883553417">     

Now I would like to attach some of 3rd parties logging tools and dlls to my project . <o:p __designer:dtid="1407374883553421">

For each tool (log4net and MSEL for example): I will create its own plug-in (interface  implementation).<o:p __designer:dtid="1407374883553426">

Each plug-in is in its own separate project, as it will be in its own assembly that is loaded by the application. The project for each plug-in uses a project reference to refer to the main interface.<o:p __designer:dtid="1407374883553431">

So we will create a project LoggingManager.MSELexpceptionsHandling and implement our logging interface in the class MSELExceptionsHandler.cs<o:p __designer:dtid="1407374883553435">

<o:p __designer:dtid="1407374883553438">     

What will be the benefits of implementing singleton pattern in our case?<o:p __designer:dtid="1407374883553443">

Why to use Singleton pattern or model ?<o:p __designer:dtid="1407374883553447">

To ensure that  a class has only one instance and provide a global point of access to it.<o:p __designer:dtid="1407374883553450">

<o:p __designer:dtid="1407374883553453">     

How to Implement Singleton ? <o:p __designer:dtid="1407374883553459">

1-      Simply by making a static global instance of the class and check is it found or not? For example the next code:<o:p __designer:dtid="1407374883553466">

class Singleton
 {
   private static Singleton instance;\\private variable declared

   // Note: Constructor is 'protected'
   protected Singleton()
   {
   }

   public static Singleton Instance()\\property declared which is used to access the privateVariable
   {
     // Use 'Lazy initialization'
     if (instance == null)
     {
       instance = new Singleton();
     }

     return instance;
   }
 }<o:p __designer:dtid="1407374883553489">

2-      Or by making a static constructor or Static ctor <o:p __designer:dtid="1407374883553496">

<o:p __designer:dtid="1407374883553499">     

And in our application we used Static ctor because it is thread safe according to ECMA standard section 9.5.3 For More information take a look at this page. <o:p __designer:dtid="1407374883553502">

http://jilc.sourceforge.net/ecma_p2_cil.shtml#_Toc524940486 <o:p __designer:dtid="1407374883553507">

 

How to load assemlies dynamically in a configurable way?<o:p __designer:dtid="1407374883553514">

In the configuration file (for example web.config or app.config) we define the assembly name for each of our plugins:<o:p __designer:dtid="1407374883553517">

<add key="MSELPlugin" value="MSELexpceptionsHandling.dll"/><!--    MSLE Plugin    --><o:p __designer:dtid="1407374883553534">

<add key="Net4LogPlugin" value="N4LexpceptionsHandling.dll"/><!--    N4L Plugin    --><o:p __designer:dtid="1407374883553551">

<o:p __designer:dtid="1407374883553554">     

Then we have a selector Key (this key will be the key which is called from our code) <o:p __designer:dtid="1407374883553557">

And set its value with the desired plug-in name. <o:p __designer:dtid="1407374883553560">

<add key="SelectedExHPlugin" value="MSELPlugin"/><!--MSLE Plugin--><o:p __designer:dtid="1407374883553575">

<o:p __designer:dtid="1407374883553578">     

Then our call in the code will be simply finding the value of this key:<o:p __designer:dtid="1407374883553581">

// Read the selected plugin (web config key) from the web config <o:p __designer:dtid="1407374883553584">

string strSelectedExHPlugin = ConfigurationManager.AppSettings["SelectedExHPlugin"];<o:p __designer:dtid="1407374883553590">

<o:p __designer:dtid="1407374883553593">     

Finally we build our configurable solution <o:p __designer:dtid="1407374883553596">

<v:shapetype id="_x0000_t75" __designer:dtid="1407374883553599" coordsize="21600,21600" o:spt="75" o:preferrelative="t" path="m@4@5l@4@11@9@11@9@5xe" filled="f" stroked="f"><v:stroke joinstyle="miter"><v:formulas><v:f eqn="if lineDrawn pixelLineWidth 0"><v:f eqn="sum @0 1 0"><v:f eqn="sum 0 0 @1"><v:f eqn="prod @2 1 2"><v:f eqn="prod @3 21600 pixelWidth"><v:f eqn="prod @3 21600 pixelHeight"><v:f eqn="sum @0 0 1"><v:f eqn="prod @6 1 2"><v:f eqn="prod @7 21600 pixelWidth"><v:f eqn="sum @8 21600 0"><v:f eqn="prod @7 21600 pixelHeight"><v:f eqn="sum @10 21600 0"><v:path o:extrusionok="f" gradientshapeok="t" o:connecttype="rect"><o:lock v:ext="edit" aspectratio="t">

Sample Image - maximum width is 600 pixels

<o:p __designer:dtid="1407374883553601">

<o:p __designer:dtid="1407374883553604">     

How to configure MSEL 2 Logging block on the fly without need for the pre-setting with MS configuraiton tool?<o:p __designer:dtid="1407374883553607">

<o:p __designer:dtid="1407374883553610">     

What will the benefits which we will gain from using this methodology ?<o:p __designer:dtid="1407374883553614">

1- Simply we will put our known readable keys in our web/app.config file for example:<o:p __designer:dtid="1407374883553617">

<o:p __designer:dtid="1407374883553620">     

<add key="LoggingFile" value="c:\Logging.txt"/><o:p __designer:dtid="1407374883553633">

<add key="LoggingFileSeperator" value="--------------------"/><o:p __designer:dtid="1407374883553647">

<o:p __designer:dtid="1407374883553650">     

Wihtout need to use the external tool or know external XML scehams and node will be added in external config file or evern our web/app.config file. <o:p __designer:dtid="1407374883553653">

<o:p __designer:dtid="1407374883553656">     

2- We will use more Sink (event logging method : event viewer ; file ; mail etc) in a more simple parameterized way without setting up policies and choose policies from the code. <o:p __designer:dtid="1407374883553659">

We will simply build our LoggingType enum and choose the suitable value to log from its values. <o:p __designer:dtid="1407374883553662">

<o:p __designer:dtid="1407374883553665">     

Then how to configure the MSEL on the fly?<o:p __designer:dtid="1407374883553668">

Special thanks for Alois Kraus for his most valuable article on his blog:

http://geekswithblogs.net/akraus1/archive/2006/02/16/69784.aspx

<o:p __designer:dtid="1407374883553676">

We built our ConfigLessLogger to configure the MSEL programatically (Add/Remove/Choose sinks)

Then we built an overlay class which is the implementer of our main logging interface. MSELExceptionsHandler.cs which will be used to build our MSEL assembly plugin; then we programmatically load this assembly from our code:

<o:p __designer:dtid="1407374883553684">

// use the returned web-config key name from the above step in getting the assembly name of <o:p __designer:dtid="1407374883553687">

// the selected implementation for the base ExH interface from the web config.<o:p __designer:dtid="1407374883553690">

            System.Reflection.Assembly asmSelectedPlugin = System.Reflection.Assembly.LoadFrom(ConfigurationManager.AppSettings[strSelectedExHPlugin]);<o:p __designer:dtid="1407374883553697">

<o:p __designer:dtid="1407374883553700">     

I hope that you Enjoy the code J

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Egypt Egypt
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralPlug-in Manager for Logging Pin
CAG_new24-Oct-06 20:27
CAG_new24-Oct-06 20:27 
GeneralRe: Plug-in Manager for Logging Pin
Mohamed Elzahaby24-Oct-06 20:47
Mohamed Elzahaby24-Oct-06 20:47 
You have to install MS application blocks v 2.0

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.