나는 항상 다음과 같은 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의 경우 구체적으로 구체적인 Adapter 클래스는 다음과 같습니다.
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 프레임 워크를 추상화하는 것입니다. 따라서 프레임 워크 간의 차이가 일반적으로 사용 구성이 아니라 구성에 있기 때문에 언제든지이를 교체 할 수 있습니다.
그러나 보너스로, IoC 프레임 워크를 본질적으로 지원하지 않는 다른 프레임 워크에서 사용하기가 훨씬 쉬워졌습니다. 예를 들어 WinForms의 경우 다음 두 단계가 있습니다.
Main 메소드에서 다른 작업을 수행하기 전에 컨테이너를 인스턴스화하십시오.
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());
}
}
}
그리고 다른 폼이 파생 된 기본 폼을 가져 와서 Inject를 호출합니다.
public IocForm : Form
{
public IocForm() : base()
{
Ioc.Container.Inject(this);
}
}
이를 통해 자동 배선 휴리스틱에 모듈에 설정된 규칙에 맞는 형식으로 모든 속성을 재귀 적으로 주입하려고합니다.