標籤:
最近和小夥伴們在做一個前台小架構, 已經有些人用起來了。 但是之前架構沒有引入 Ioc, 所以使用者實現我們架構開放出去的介面後,我們只能通過反射來擷取使用者的實作類別。這樣一個問題就是我們雖然定義了介面, 但其實我們依然依賴於使用者的實現,同時架構啟動異常的慢。 所以我們打算使用開源 Ioc 架構來把完成依賴注入的動作。 我們就完全關心我們自己的介面, 然後使用者可以自己把實作類別注入到架構中來,這樣不僅移除了依賴,同是也砍掉了反射,可以加快載入速度。
因為開放的介面中定義了泛型介面,所以選中支援泛型介面的 Unity 來完成 Ioc 功能。 下面一步步實現一個簡單的 Unity 泛型介面執行個體。
首先定義三個項目:
- UnityPrimer 架構代碼
- UnityPrimerClient 架構使用者代碼
- UnityPrimerInterfaces 架構介面
項目結構
架構介面包含:
- 實體介面
namespace UnityPrimerInterfaces.Interfaces{ public interface IModel { string Name { get; set; } }}
- 泛型介面
namespace UnityPrimerInterfaces.Interfaces{ public interface IEnricher<T> where T:IModel { T StringToModel(string message); string ModelToString(T model); }}
架構使用者實現代碼:實現架構定義的介面,並且把實現執行個體注入到容器中。
- 介面實現
public class Model :IModel { private string name; public string Name { get { return name; } set { name = value; } } }
public class Enricher<T> : IEnricher<T> where T:IModel { public T StringToModel(string message) { var model =new Model() { Name = message }; return (T)((IModel)model); } public string ModelToString(T model) { return model.Name; } }
- 註冊器
namespace UnityPrimerClient{ public class Register { public static IUnityContainer Container; public static void Regist() { Container = new UnityContainer(); Container.RegisterType(typeof(IEnricher<>), typeof(Enricher<>), "Sample"); //Container.RegisterType(typeof(IEnricher<IModel>), typeof(Enricher<Model>), "Sample"); //Container.RegisterInstance<IEnricher<IModel>>(new Enricher<Model>()); } }}
架構代碼:架構從容器中擷取使用者實現的對象,並進行操作。
namespace UnityPrimer{ class Program { static void Main(string[] args) { Register.Regist(); var enricher = Register.Container.Resolve<IEnricher<IModel>>("Sample"); IModel model = enricher.StringToModel("SampleModel"); Console.WriteLine(enricher.ModelToString(model)); Console.ReadLine(); } }}
對於 Unity 來說,最容易出錯的部分,就是 register 和 resolve 的時候。同是對於泛型介面,泛型約束會導致resolve失敗。
C# Unity 對於泛型介面的支援