Saya selalu menulis bungkus Adaptor untuk Kontainer IoC, yang terlihat seperti ini:
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>();
}
Untuk Ninject, khususnya, kelas Adapter beton terlihat seperti ini:
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);
}
}
Alasan utama untuk melakukan ini adalah untuk abstrak kerangka kerja IoC, jadi saya bisa menggantinya kapan saja - mengingat bahwa perbedaan antara kerangka kerja umumnya dalam konfigurasi daripada penggunaan.
Tetapi, sebagai bonus, banyak hal juga menjadi jauh lebih mudah untuk menggunakan kerangka kerja IoC di dalam kerangka kerja lain yang tidak secara inheren mendukungnya. Untuk WinForms, misalnya, ini adalah dua langkah:
Dalam metode Utama Anda, cukup instantiate sebuah wadah sebelum melakukan hal lain.
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());
}
}
}
Dan kemudian memiliki Formulir dasar, dari mana bentuk lain berasal, yang memanggil Suntikan itu sendiri.
public IocForm : Form
{
public IocForm() : base()
{
Ioc.Container.Inject(this);
}
}
Ini memberi tahu heuristik pengkabelan otomatis untuk mencoba menyuntikkan semua properti secara rekursif dalam bentuk yang sesuai dengan aturan yang diatur dalam modul Anda.