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())
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
{
}
}
#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
{
}
catch (Exception exception)
{
exception.Log();
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