I am developing an internal library that is to be used by other developers in the company that I'm working for. I am applying SOLID patterns and following the best practices as described in Dependency Inject (DI) “friendly” library.
My end users would be developers of different applications. Some of them are complex legacy applications with no DI, and others are newer apps that have DI and TDD.
Now, I am trying to figure out how to call this DI friendly library from a legacy ASP.NET Webforms application that has no DI implemented in it, and obviously, I can't revise 250+ aspx pages to support constructor injection because it is out of scope of my project. (Yes, I have read Introducing an IoC Container to Legacy Code )
One idea that I had was creating a static global wrapper for Common Service Locator to automatically resolve dependencies throughout the app:
public static class GlobalResolver
{
public static T Resolve<T>()
{
return ServiceLocator.Current.GetInstance<T>();
}
}
The nice thing about this approach is that I can use any IoC library in my composition root (I currently use Unity). I would use this GlobalResolver like this:
protected void OnClick(object sender, EventArgs e)
{
IMailMessage message = MessageFactory.Create("Jack.Daniels@jjj.com", "John.Doe@jjj.com", "subject", "Body", true, MailPriority.High);
GlobalResolver.Resolve<IMailer>().SendMail(message);
}
I like this approach and I think it's clean, but novice developers in my company might get confused with this GlobalResolver.Resolve<IMailer>
line, so I'm trying to see if there is alternative to this out there.
One thing that comes to my mind is something like this:
public static class CommonCatalog
{
public static IMailer Mailer => ServiceLocator.Current.GetInstance<IMailer>();
public static IMailMessageFactory MessageFactory => ServiceLocator.Current.GetInstance<IMailMessageFactory>();
public static IFtpSecureClientFactory FTPClientFactory => ServiceLocator.Current.GetInstance<IFtpSecureClientFactory>();
// And so on...
}
And simply use it like this: CommonCatalog.Mailer.SendMail(message);
. Developers at my company are used to seeing static methods, and I think this approach might be desirable for them.
My questions are:
- Is this the best solution for my problem?
- Am I violating any of the best practices?
- Is there a design pattern that descibes the CommonCatalog class? Is it a "Facade" or "Proxy"?
TLDR: Developers at my company like to use Static methods, but static methods are incompatible with DI and SOLID practices. Is there any way to trick people into thinking that they are using static methods, but behind the scenes call DI code?