Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Extensions - what can I do with them

0.00/5 (No votes)
29 Sep 2008 1  
What are the possibilities of extension classes? See how you use them to provide logging facilities automagically

Extensions… are they useful?

With the introduction of .net 3.5 along came extensions. Extension classes are a way of extending types by adding functionality, even to types you don’t have the source code to.
With that we can extend for example the string to validate if a string is a valid email address.

public static bool IsValidEmailAddress(this string s)
{
   Regex regex = new Regex(@"^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$");
   return regex.IsMatch(s); 
}

and to use it, we do…

bool isEmail = teststring.IsValidEmailAddress();

Within extension classes we can also use generics, so we could extend system.object to return all the public properties of an object.

public static List<PropertyInfo> Properties<T>(this T item)
{
    List<PropertyInfo> list = new List<PropertyInfo>();
    foreach (PropertyInfo property in item.GetType().GetProperties())
        list.Add(property);
    return list;
}

And the usage will be…

object testObj = new object();
foreach (PropertyInfo property in testObj.Properties())
    /*.do something*/

Real world

Ok, so how’s this really beneficial to us . Let’s attempt a real world scenario.

A common requirement in modern applications is the ability to log information, log exceptions and warnings.  We’re going to create a basic logging solution and add an extension method to make logging simpler and available to ALL exceptions in our application.

below is the code for the logging solution. Its just some sample code to get us through the article.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Fuzzelogic.Samples.Logging
{
    public interface ILogProvider
    {
        void Log(LoggingTypes type, string message);
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace Fuzzelogic.Samples.Logging
{
    public enum LoggingTypes
    {
        Warning,
        Information,
        Exception
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO; 

namespace Fuzzelogic.Samples.Logging
{
    public class FileLogger : ILogProvider
    {
        string _FileName = "";
        public FileLogger(string fileName)
        {
            _FileName = fileName;
        }

#region ILogProvider Members
        public void Log(LoggingTypes type, string message)
        {
            string formattedMessage = string.Format ( "{0} : {1}\n", type.ToString(), 
                                                      message );
            try
            {
                File.AppendAllText(_FileName, formattedMessage);
            }
            catch
            {
                // Do nothing.
            }
        }
#endregion
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Fuzzelogic.Samples.Logging
{
    public class Logger
    {
        static List _Providers = new List();

        public static void Register(ILogProvider provider)
        {
            if (!_Providers.Contains(provider))
                _Providers.Add(provider);
        }

        public static void Log(LoggingTypes type, string message)
        {
            foreach (ILogProvider provider in _Providers)
                provider.Log(type, message);
        }
    }
}

Now here’s the exciting part.

First we create the extension class.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Fuzzelogic.Samples.Logging;
 
namespace Fuzzelogic.Samples.Extensions
{
    public static class ExceptionExtensions
    {
        public static void Log(this Exception exception)
        {
            string message = string.Format("{0}\n{1}", exception.Message, 
                                           exception.ToString());
            Logger.Log(LoggingTypes.Exception, message); 
        }
    }
}

OK, so now we have the logging solution, the extension class, and here’s how we now log exceptions.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Fuzzelogic.Samples.Extensions;
 
namespace Fuzzelogic.Samples.TestCode
{
    public class LoggingTests
    {
        public void TestMethod()
        {
            try
            {
                /* Do something */
            }
            catch (Exception exception)
            {
                exception.Log(); // Thats all thats needed on ALL exception objects.
                throw;
            }
        }
    }
}

Hmm… so how about make the logging go further. How about the following extension…

public static class ObjectExtensions
{
    public static void Log(this object anObject, LoggingTypes type, string message)
    {
        string logMessage = string.Format("{0}:{1}", DateTime.Now.ToString(), message);
        Logger.Log(type, logMessage);
    }
}

So now every object has the ability to log information and warnings, even exceptions.

object someThing = new object();
someThing.Log(LoggingTypes.Information, "Some information message");

I’m sure there’s more to extensions, but for now the possibilities are bright . Hope this helps.

fuzzelogic Solutions.com

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