标签:
上篇文章介绍了如何利用反射类查找网站bin文件夹下面所有DLL的程序集类,这篇文章将介绍如何初始化一个IOC容器引擎。
目前IOC容器有很多,如Ninject,Autofac等,每个容器的驱动都不一样,为了方便驱动解耦,好使用不同的IOC容器,就得有一个公共接口。
1. IEngine (引擎接口)
public interface IEngine {
//#region Initialize
//void Initialize();
//#endregion
#region ContainerManager
IContainerManger ContainerManager { get; }
#endregion
#region Resolve
T Resolve<T>(params Parameter[] parameters) where T : class;
T Resolve<T>(string name, params Parameter[] parameters) where T : class;
object Resolve(Type type, params Parameter[] parameters);
object Resolve(Type type, string name, params Parameter[] parameters);
#endregion
#region TryResolve
T TryResolve<T>(params Parameter[] parameters) where T : class;
T TryResolve<T>(string name, params Parameter[] parameters) where T : class;
object TryResolve(Type type, params Parameter[] parameters);
object TryResolve(Type type, string name, params Parameter[] parameters);
#endregion
#region ResolveAll
IEnumerable<Object> ResolveAll(Type serviceType);
IEnumerable<T> ResolveAll<T>();
#endregion
}
接口主要约束:解析,试图解析,解析所有三个方法,都采用实例和泛型两个版本来写。PS:泛型就是实例的约束版而已,但线程是安全的。
2.EngineContext(引擎上下文)
public class EngineContext {
#region Initializtion Methods
/// <summary>
/// 确保方法同步实例化
/// </summary>
/// <param name="forceRecreate"></param>
/// <returns></returns>
[MethodImpl(MethodImplOptions.Synchronized)]
public static IEngine Initialize(bool forceRecreate)
{
if (Singleton<IEngine>.Instance == null || forceRecreate)
{
Singleton<IEngine>.Instance = CreateEngineInstance();
//Singleton<IEngine>.Instance.Initialize();
}
return Singleton<IEngine>.Instance;
}
#endregion
public static IEngine CreateEngineInstance()
{
var typeFinder = new WebAppTypeFinder();
var engines = typeFinder.FindClassesOfType<IEngine>().ToArray();
if (engines.Length > 0)
{
var defaultEngine =(IEngine)Activator.CreateInstance(engines[0]);
return defaultEngine;
}
else
{
throw new ApplicationException("找不到IOC容器");
}
}
public static IEngine Current
{
get
{
if (Singleton<IEngine>.Instance == null)
{
Initialize(false);
}
return Singleton<IEngine>.Instance;
}
}
}
引擎上下文:为了保证系统线程当中可以高性能的使用容器驱动,又是唯一的实例,所以使用单例类进行托管
3.Singleton(单列类)
/// <summary>
/// 单列模式保持唯一性 提高性能
/// </summary>
public class Singleton
{
/// <summary>
/// 字典数组
/// </summary>
private static readonly IDictionary<Type, object> allSingletons;
static Singleton()
{
allSingletons=new Dictionary<Type, object>();
}
public static IDictionary<Type, object> AllSingletons
{
get
{
return allSingletons;
}
}
}
/// <summary>
/// 单列泛型模式
/// </summary>
/// <typeparam name="T"></typeparam>
public class Singleton<T> : Singleton
{
private static T _instance;
public static T Instance
{
get
{
return _instance;
}
set
{
_instance = value;
AllSingletons[typeof (T)] = value;
}
}
}
/// <summary>
/// 单列泛型数组模式
/// </summary>
/// <typeparam name="T"></typeparam>
public class SingletonList<T> : Singleton<IList<T>>
{
static SingletonList()
{
Singleton<IList<T>>.Instance=new List<T>();
}
public new static IList<T> Instance
{
get
{
return Singleton<IList<T>>.Instance;
}
}
}
/// <summary>
/// 单列字典模式
/// </summary>
/// <typeparam name="TKey"></typeparam>
/// <typeparam name="TValue"></typeparam>
public class SingletonDictionary<TKey, TValue> : Singleton<IDictionary<TKey, TValue>>
{
static SingletonDictionary()
{
Singleton<Dictionary<TKey,TValue>>.Instance=new Dictionary<TKey, TValue>();
}
public new static IDictionary<TKey, TValue> Instance
{
get
{
return Singleton<Dictionary<TKey, TValue>>.Instance;
}
}
}
单例类:防止重复创建实例。
上面主要是容器接口,上下文等封装,要使用具体的IOC那就得继承IEngine这个接口。
这里使用的是Ninject接口类:
4.NinjectEngine(实现IEngine接口)
public class NinjectEngine:IEngine {
#region Properties
public IContainerManger ContainerManager
{
get;
private set;
}
public ITypeFinder TypeFinder
{
get;
private set;
}
#endregion
#region .ctor
public NinjectEngine(ITypeFinder typeFinder):this(typeFinder,new ContainerManager())
{}
public NinjectEngine(ITypeFinder typeFinder, ContainerManager containerManager)
{
if (typeFinder == null)
{
throw new ArgumentException("没有反射类查找器");
}
this.TypeFinder = typeFinder;
this.ContainerManager = containerManager;
InitializeContainer();
}
#endregion
#region Methods
private void InitializeContainer() {
var attrDependency = new DependencyAttributeRegistrator(this.TypeFinder, this.ContainerManager);
attrDependency.RegisterServices();
}
public T Resolve<T>(params Parameter[] parameters) where T : class
{
return ContainerManager.Resolve<T>(null, parameters);
}
public T Resolve<T>(string name, params Parameter[] parameters) where T : class
{
return ContainerManager.Resolve<T>(name, parameters);
}
public object Resolve(Type type, params Parameter[] parameters)
{
return ContainerManager.Resolve(type, null, parameters);
}
public object Resolve(Type type, string name, params Parameter[] parameters) {
return ContainerManager.Resolve(type, name, parameters);
}
public T TryResolve<T>(params Parameter[] parameters) where T : class
{
return ContainerManager.TryResolve<T>(null, parameters);
}
public T TryResolve<T>(string name, params Parameter[] parameters) where T : class
{
return ContainerManager.TryResolve<T>(name, parameters);
}
public object TryResolve(Type type, params Parameter[] parameters)
{
return ContainerManager.TryResolve(type, null, parameters);
}
public object TryResolve(Type type, string name, params Parameter[] parameters)
{
return ContainerManager.TryResolve(type, name, parameters);
}
public IEnumerable<object> ResolveAll(Type serviceType)
{
return ContainerManager.ResolveAll(serviceType);
}
public IEnumerable<T> ResolveAll<T>()
{
return ContainerManager.ResolveAll<T>();
}
#endregion
}
引擎初始化大致过程是这样的。接口=>程序集查找=>实现接口的IOC容器类=>写入单列=>形成容器驱动上下文
《转》IOC容器特性注入第二篇:初始引擎查找对应的IOC容器
标签:
原文地址:http://www.cnblogs.com/DoveZoe/p/5454241.html