目录

什么是IoC

IoC是英文Inversion of Control的缩写,通称”控制反转“.
主要用来解决依赖倒置.
可以更好的实现面向接口编程,使各组件解耦.

实现

1.定义IIoCConfig

1
2
3
4
5
6
public interface IIoCConfig
{
void AddConfig<TInterface, TType>();

Dictionary<Type, Type> ConfigDictionary { get; }
}

2.定义IoCConfig实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public class IoCConfig : IIoCConfig
{
/// <summary>
/// 存放配置的字典对象, Key是接口类型, Value是实现接口的类型
/// </summary>
private Dictionary<Type, Type> _configDictionary = new Dictionary<Type, Type>();

/// <summary>
/// 添加配置
/// </summary>
/// <typeparam name="TInterface">接口</typeparam>
/// <typeparam name="TType">实现接口的类型</typeparam>
public void AddConfig<TInterface, TType>()
{
if (typeof(TInterface).IsAssignableForm(typeof(TType)))
{
_configDictionary.Add(typeof(TInterface), typeof(TType));
}
else
{
throw new Exception("类型未实现接口");
}
}

public Dictionary<Type, Type> ConfigDictionary
{
get
{
return _configDictionary;
}
}
}

使用一个字典来保存Interface跟Class的对应关系.
这里是仿造Ninject的配置方式,使用代码来配置.
这种配置方式有个好处就是不会写错,因为有IDE来给你检查拼写错误.

3.定义IoCContainer容器接口

1
2
3
4
5
6
7
8
9
public interface IIoCContainer
{
/// <summary>
/// 根据接口返回对应的实例
/// </summary>
/// <typeparam name="TInterface"></typeparam>
/// <returns></returns>
TInterface Get<TInterface>();
}

4.使用反射实现IoC容器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
public class ReflectionContainer : IIoCContainer
{
/// <summary>
/// 配置实例
/// </summary>
private IIoCConfig m_config;


/// <summary>
/// 构造函数
/// </summary>
/// <param name="_config">ioc配置</param>
public ReflectionContainer(IIoCConfig _config)
{
m_config = _config;
}

/// <summary>
/// 根据接口获取实例对象
/// </summary>
/// <typeparam name="TInterface">接口</typeparam>
/// <returns></returns>
public TInterface Get<TInterface>()
{
Type _type;

var _can = m_config.ConfigDictionary.TryGetValue(typeof(TInterface), out _type);

if(_can)
{
// 反射实例化对象
return (TInterface)Activator.CreateInstance(_type);
}
else
{
throw new Exception("未找到队友的类型");
}
}
}

5.使用Emit实现IoC容器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
public class EmitContainer : IIOCContainer
{
private IIoCConfig m_config;

public EmitContainer(IIoCConfig _config)
{
m_config = _config;
}

public TInterface Get<TInterface>()
{
Type _type;

var _can = m_config.ConfigDictionary.TryGetValue(typeof(TInterface), out _type);

if (_can)
{
BindingFlags _defaultFlags = BindingFlags.Public | BindingFlags.Instance;

// 获取默认构造函数
var _constructors = _type.GetConstructors(_defaultFlags);

var _t = (TInterface)this.CreateInstanceByEmit(_constructors[0]);

return _t;
}
else
{
throw new Exception("未找到对应的类型");
}
}

private Object CreateInstanceByEmit(ConstructInfo _constructor)
{
//动态方法
var _dynamicMethod = new DynamicMethod(Guid.NewGuid().ToString("N"), typeof(Object), new[] { typeof(object[]) }, true);

//方法IL
ILGenerator _il = _dynamicMethod.GetILGenerator();

//实例化命令
_il.Emit(OpCodes.Newobj, constructor);

//如果是值类型装箱
if (constructor.ReflectedType.IsValueType)
{
_il.Emit(OpCodes.Box, constructor.ReflectedType);
}

//返回
_il.Emit(OpCodes.Ret);

//用FUNC去关联方法
var _func = (Func<Object>)_dynamicMethod.CreateDelegate(typeof(Func<Object>));

//执行方法
return _func.Invoke();
}
}

6.实现IoCContainerManager

1
2
3
4
5
6
7
8
9
public class IoCContainerManager
{
/// <summary>
/// 容器
/// </summary>
private static IIOCContainer m_container;

public static IIOCContainer
}