Strategy Pattern With Ninject
This is a follow-up to my post about avoiding dependencies with design patterns. It left off with something like this as a Cart object that uses the Strategy pattern to avoid a direct dependency on SMTP emails.
1: public class Cart
2: {3: private ISendEmail emailProvider;
4: //public Cart()
5: //{
6: // emailProvider = new LiveSmtpMailer();
7: //}
8: 9: public Cart(ISendEmail emailProvider)
10: {11: this.emailProvider = emailProvider;
12: } 13: 14: public void Checkout()
15: {16: // Do some other stuff
17: 18: this.emailProvider.SendMail("someuser@domain.com", "store@acme.com",
19: "Order Confirmation", "Your Order Was Received.");
20: } 21: }Note that I've commented out the default constructor - I'll explain why in a moment.
The next logical step in this series is to avoid the requirement of hard-coding in the class its default behavior of using a LiveSmtpMailer() instance to send email. We want to be able to manage these default implementations centrally, either via a class or some kind of configuration file. Tools that provide this functionality are collectively referred to as Inversion-of-Control containers, or IoC containers. Ninject is one such tool.
Download Ninject, build it if necessary, and add a reference to Ninject.Core to get started. With this in place, we can do the necessary plumbing work to have Ninject instantiate our Cart class for us, rather than using the new keyword ourselves directly. Avoiding the new keyword is a necessary consequence of most IoC containers, as far as I can tell. To tell Ninject what to do when it finds it needs an ISendEmail interface implementation, you can create something like the following:
1: public class CustomModule : StandardModule
2: {3: public override void Load()
4: { 5: Bind<ISendEmail>().To<ConsoleTestMailer>(); 6: } 7: }The ConsoleTestMailer is a new one I wrote for this example. It's listed here:
1: public class ConsoleTestMailer : ISendEmail
2: {3: public void SendMail(string To, string From, string Subject, string Body)
4: {5: Console.WriteLine("To: " + To);
6: Console.WriteLine("From: " + From);
7: Console.WriteLine("Subject: " + Subject);
8: Console.WriteLine("Body: " + Body);
9: } 10: }All it does is dump the email information to the console.
Now we're ready to write the Main() method of our console application:
1: class Program
2: {3: static void Main(string[] args)
4: {5: CustomModule module = new CustomModule();
6: IKernel kernel = new StandardKernel(module);
7: 8: Cart myCart = kernel.Get<Cart>(); 9: myCart.Checkout(); 10: } 11: }