Good morning!
Yesterday I watched Tekpub's amazing video "Dependency Injection and Inversion of Control" and it blew my mind. I feel like this is how I should be writing code. I have watched it before and even experimented with Ninject a little bit, but feel like I need some more examples of code being refactored into this paradigm.
The brief MUD example he goes into is great, but does anyone know of a site or project where they start with some ugly, but working, code and then refactor it into clean Dependency Injected code?
While I can find examples of code that use Dependency Injection pretty easily, I am having a hard time finding before/after code and I feel like this would greatly help me start programming "at the next level". I need a few more examples to really wrap my head around it.
Suppose you wanted to implement a spelling correction service. Input a word/phrase and out pops a corrected version of the word/phrase. What if you were depending on a large, online provider that went down for a day. Ideally, you would implement a backup in case the request to said provider failed. In that backup, you might call your secondary service and hope they're online. Maybe in a last ditch effort in the event they're both down, you implement an offline provider to correct spelling based on a local dictionary that exists on the file system.
How do you manage multiple providers like this?
Before
public class SpellCheck
{
public string FixText(string text)
{
string CorrectedText = string.Empty;
// create HTTP request to Online Provider #1
// return CorrectedText;
}
}
After
public class SpellCheck
{
private readonly IOnlineSpellService _onlineSpell;
private readonly IOfflineSpellService _offlineSpell;
public SpellCheck(IOnlineSpellService onlineSpell,
IOfflineSpellService offlineSpell)
{
this._onlineSpell = onlineSpell;
this._offlineSpell = offlineSpell;
}
// same method as before, just a slightly different implementation
public string FixText(string text)
{
string fixedText = _onlineSpell.FixText(text);
if(_onlineSpell.Failed)
fixedText = _offlineSpell.FixText(text);
return fixedText;
}
}
Of course, you'd need to implement the interface ISpellOnlineService (and similar interface for ISpellOfflineService
public interface ISpellOnlineService
{
public bool Failed { get; set; }
public string FixText(string text);
}
Next, implement your spelling providers (both online and offline, or even multiple instances of both to gain more flexibility)
public class OnlineProviderNo1 : IOnlineSpellService
{
public string FixText(string text)
{
// implement online logic
this.Failed = false;
}
}
Finally, register your services by overriding the CreateKernel method and subclassing your MvcApplication from NinjectHttpApplication. And apparently with Ninject you replace Application_Start with an override called OnApplicationStarted like so:
**This done in global.asax
public class MvcApplication : NinjectHttpApplication
{
// ...
protected override void OnApplicationStarted()
{
base.OnApplicationStarted();
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
}
protected override IKernel CreateKernel()
{
var kernel = new StandardKernel();
kernel.Bind<IOnlineSpellService>().To<OnlineProviderNo1>();
kernel.Bind<IOfflineSpellService>().To<OfflineProviderNoX>();
return kernel;
}
}
Yes, this is a real world example, as I've implemented it (I actually used Castle Windsor, but it's the identical concept with Ninject--just adapted above) with 3 online providers and 2 offline providers. In CreateKernel you may choose to include logic to examine a database, config file, etc to determine which provider to register. For example, maybe one service has announced 24 hours of downtime (hopefully, you're lucky enough to have that announced!) so during that time you want to switch to another online provider for which you've implemented an instance of IOnlineSpellService