IOC容器特性注入第二篇:初始引擎查找对应的IOC容器
上篇文章介绍了如何利用反射类查找网站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容器类=>写入单列=>形成容器驱动上下文
下一篇: