Her zaman şöyle görünen herhangi bir IoC Konteyneri için bir Adaptör sarıcısı yazarım:
public static class Ioc
{
public static IIocContainer Container { get; set; }
}
public interface IIocContainer
{
object Get(Type type);
T Get<T>();
T Get<T>(string name, string value);
void Inject(object item);
T TryGet<T>();
}
Özellikle Ninject için, somut Bağdaştırıcı sınıfı şöyle görünür:
public class NinjectIocContainer : IIocContainer
{
public readonly IKernel Kernel;
public NinjectIocContainer(params INinjectModule[] modules)
{
Kernel = new StandardKernel(modules);
new AutoWirePropertyHeuristic(Kernel);
}
private NinjectIocContainer()
{
Kernel = new StandardKernel();
Kernel.Load(AppDomain.CurrentDomain.GetAssemblies());
new AutoWirePropertyHeuristic(Kernel);
}
public object Get(Type type)
{
try
{
return Kernel.Get(type);
}
catch (ActivationException exception)
{
throw new TypeNotResolvedException(exception);
}
}
public T TryGet<T>()
{
return Kernel.TryGet<T>();
}
public T Get<T>()
{
try
{
return Kernel.Get<T>();
}
catch (ActivationException exception)
{
throw new TypeNotResolvedException(exception);
}
}
public T Get<T>(string name, string value)
{
var result = Kernel.TryGet<T>(metadata => metadata.Has(name) &&
(string.Equals(metadata.Get<string>(name), value,
StringComparison.InvariantCultureIgnoreCase)));
if (Equals(result, default(T))) throw new TypeNotResolvedException(null);
return result;
}
public void Inject(object item)
{
Kernel.Inject(item);
}
}
Bunu yapmanın birincil nedeni, IoC çerçevesini soyutlamaktır; bu nedenle, çerçeveler arasındaki farkın genellikle kullanımdan ziyade yapılandırmada olduğu göz önüne alındığında, istediğim zaman değiştirebilirim.
Ancak, bir bonus olarak, IoC çerçevesini doğal olarak desteklemeyen diğer çerçevelerde kullanmak çok daha kolay hale geliyor. WinForms için, örneğin, iki adımdır:
Ana yönteminizde, başka bir şey yapmadan önce bir kabı başlatmanız yeterlidir.
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
try
{
Ioc.Container = new NinjectIocContainer( /* include modules here */ );
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MyStartupForm());
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
}
Ve sonra başka biçimlerin türetildiği ve Kendisini enjekte eden temel bir Form'a sahip olun.
public IocForm : Form
{
public IocForm() : base()
{
Ioc.Container.Inject(this);
}
}
Bu, otomatik kablolama sezgiseline, modüllerinizde belirlenen kurallara uyan formdaki tüm özellikleri art arda enjekte etmeye çalışmalarını söyler.