Skip to content

Instantly share code, notes, and snippets.

@nonnb
Created March 12, 2017 10:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nonnb/82df8e127cf7d6c6e4d6d6032566903c to your computer and use it in GitHub Desktop.
Save nonnb/82df8e127cf7d6c6e4d6d6032566903c to your computer and use it in GitHub Desktop.
StackOverflow21285090 - Alternatives to Abstract Factory pattern using Ninject
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using Ninject;
using Ninject.Modules;
namespace WindowsFormsApplication5
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
// Obviously I'm abusing Ninject as a Service Locator here rather than a dependency injector
// but the build up of dependencies is still demonstrated.
IKernel kernel = new StandardKernel(new FooModule());
var theScreen = kernel.Get<Screen>();
// Like abstract factory, the actual concrete class returned can be flavoured,
// either by a parameter, attributes, or even ambient context.
theScreen.AddButton(ButtonType.CancelButton);
theScreen.AddButton(ButtonType.OKButton);
theScreen.AddButton(ButtonType.ExitButton);
}
}
public interface IButton
{
}
public class OkButton : IButton
{
}
public class CancelButton : IButton
{
}
public class ExitButton : IButton
{
}
public enum ButtonType
{
OKButton,
CancelButton,
ExitButton
};
public class FooModule : NinjectModule
{
public override void Load()
{
Bind<Func<ButtonType, IButton>>()
.ToMethod(
context =>
{
return (buttonType =>
{
switch (buttonType)
{
case ButtonType.OKButton:
return new OkButton();
case ButtonType.CancelButton:
return new CancelButton();
case ButtonType.ExitButton:
return new ExitButton();
default:
throw new ArgumentException("buttonType");
}
});
});
// TODO : It would be cleaner to separate each of the predicates into its own registration
// http://stackoverflow.com/a/15270745/314291
// But doing this elegantly eludes me
// Bind<Func<ButtonType, IButton>>()
// .ToMethod(context => x => new OkButton())
// .When(request => request.Parameters.First().GetValue() == ButtonType.OKButton);
// Bind<Func<ButtonType, IButton>>()
// .ToMethod(context => x => new CancelButton())
// .When(request => request.Parameters.First().GetValue() == ButtonType.CancelButton);
}
}
public class Screen
{
private readonly Func<ButtonType, IButton> _buttonResolver;
private readonly IList<IButton> _buttons;
public Screen(Func<ButtonType, IButton> buttonResolver)
{
_buttonResolver = buttonResolver;
_buttons = new List<IButton>();
}
public void AddButton(ButtonType type)
{
var newButton = _buttonResolver(type);
_buttons.Add(newButton);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment