मैं हमेशा किसी भी IoC कंटेनर के लिए एक एडॉप्टर आवरण लिखता हूं, जो इस तरह दिखता है:
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>();
}
Ninject के लिए, विशेष रूप से, ठोस एडेप्टर वर्ग इस तरह दिखता है:
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);
}
}
ऐसा करने का प्राथमिक कारण आईओसी ढांचे का सार है, इसलिए मैं इसे किसी भी समय बदल सकता हूं - यह देखते हुए कि फ्रेमवर्क के बीच का अंतर आमतौर पर उपयोग के बजाय कॉन्फ़िगरेशन में है।
लेकिन, एक बोनस के रूप में, अन्य ढाँचों के अंदर IoC ढांचे का उपयोग करने के लिए चीजें बहुत आसान हो जाती हैं जो स्वाभाविक रूप से इसका समर्थन नहीं करते हैं। WinForms के लिए, उदाहरण के लिए, यह दो चरण हैं:
अपनी मुख्य विधि में, बस कुछ भी करने से पहले एक कंटेनर को तुरंत हटा दें।
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());
}
}
}
और फिर एक आधार फॉर्म होता है, जिसमें से अन्य रूप निकाले जाते हैं, जो खुद को इंजेक्ट कहता है।
public IocForm : Form
{
public IocForm() : base()
{
Ioc.Container.Inject(this);
}
}
यह ऑटो-वायरिंग हेयुरिस्टिक को उस रूप में सभी गुणों को पुन: इंजेक्ट करने का प्रयास करने के लिए कहता है जो आपके मॉड्यूल में स्थापित नियमों को फिट करते हैं।