Hopefully, after reading Part 1, Part 2, Part 3, Part 4 and Part 5, you should've become an Extension Method Master.
But there's more. There are other elements that can be simplified by using extension methods and that is, limiting usage of reflection.
Given something like:
public interface IServiceLocator
{
T Resolve();
}
It is important to notice that the generic method Resolve has a type parameter for the sole purpose of providing the type to resolve. There are NO constraints.
One might use the service locator as follows:
public ILogger GetLogger()
{
ILogger logger = serviceLocator.Resolve<ILogger>();
return logger;
}
But what if the type to resolve is only known at runtime? You'll have to fallback on reflection:
public static class ServiceLocatorExtensions
{
public static object Resolve(this IServiceLocator locator, Type type)
{
MethodInfo resolveMethodInfo = typeof(IServiceLocator).GetMethod("Resolve");
resolveMethodInfo = resolveMethodInfo.MakeGenericMethod(type);
return resolveMethodInfo.Invoke(serviceLocator, null);
}
}
This approach can have terrible performance, especially since there is no reflection cache.
A far better approach is to define your IServiceLocator interface as a non-generic interface and provide strongly-typed extension methods:
public interface IServiceLocator
{
object Resolve(Type type);
}
and
public static class ServiceLocatorExtensions
{
public static T Resolve(this IServiceLocator locator)
{
return (T)locator.Resolve(typeof(T));
}
}
Thoughts?
