IoC简介
IoC(Inversion of Control)翻译为“控制翻转”,这个“翻转”指的“获得依赖对象的过程被翻转了”。
IoC思想出现之前,我们想实例化一个对象,就必须在需要的地方new这个对象,然后才能使用这个对象中的成员。这样做的虽然很方便,但是久而久之代码中到处都是分散new的对象,且每个对象的生命周期都无法得到有效管理,最终导致对象管理成为项目开发的一个沉重的包袱。
如何摆脱这种困境呢——那就专门找一个模块做这个事情,这个模块就是IoC容器(容器是一种形象的说法,IoC就像一个碗,里面可以盛放对象,想要对象,不要再到处new了,直接从这个碗里面取)。
IoC的实现使得获取依赖对象的过程由自身管理变为由IoC主动注入,因此,IoC还有一个更容易理解的别名“依赖注入”。
先写一个简易版IOC实现类
说明:
- 利用反射机制获取程序集中的所有包含定制属性标记的类型;
- 根据定制属性类型进行实例化;
- 将该实例化对象,存放到IoC容器字典中;
/// <summary>
/// IOC容器
/// </summary>
public class IOCContainer
{
private static readonly Hashtable _registrations = new Hashtable();
public static void RegisterTransient<TInterface, TImplementation>()
{
if (!_registrations.ContainsKey(typeof(TInterface)))
{
_registrations.Add(typeof(TInterface), typeof(TImplementation));
}
}
public static TInterface Create<TInterface>()
{
var typeOfImpl = (Type)_registrations[typeof(TInterface)];
if (typeOfImpl == null)
{
throw new ApplicationException($"Failed to resolve {typeof(TInterface).Name}");
}
return (TInterface)Activator.CreateInstance(typeOfImpl);
}
public static T Resolve<T>()
{
var ctor = ((Type)_registrations[typeof(T)]).GetConstructors()[0];
var dep = ctor.GetParameters()[0].ParameterType;
var mi = typeof(IOCContainer).GetMethod("Create");
var gm = mi.MakeGenericMethod(dep);
return (T)ctor.Invoke(new object[] { gm.Invoke(null, null) });
}
public static TInterface GetInstance<TInterface, TImplementation>()
{
RegisterTransient<TInterface, TImplementation>();
return Resolve<TInterface>();
}
}
编写测试类和接口:
public interface ICService
{
int test();
}
public class CallService : ICService
{
public int test()
{
return 1000;
}
}
测试:
var cService = IOCContainer.GetInstance<ICService, CallService>().test();
得到结果:1000
在上面的源代码中,容器使用IOCContainer.Resolve()方法创建CallService类的一个对象。因此,IOCContainer.Resolve() 通过自动创建返回CallService类的一个对象。
这是一个非常简单和基本的IoC容器,它向你展示了IoC容器背后的内容。