標籤:
上篇文章介紹了如何利用反射類尋找網站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容器