Castle~實現IoC容器
IOC的容器確實不少,unity,autofac,Castle 等(deng)等(deng),前(qian)兩種組件如(ru)何(he)(he)實現(xian)IOC在(zai)我之前(qian)的文章中已經做(zuo)過(guo)說明了(le),今天主要(yao)(yao)來說一(yi)下(xia)Castle如(ru)何(he)(he)去實現(xian)IoC,事(shi)實上Castle是小微的一(yi)個(ge)開源項(xiang)目,最早接(jie)觸它是在(zai)orchard項(xiang)目中,在(zai)orchard里主要(yao)(yao)用在(zai)動態代理方法攔截(jie)上,當然(ran)這是castle最重要(yao)(yao)的作用,事(shi)實上它當然(ran)也可以實現(xian)IoC了(le),不(bu)過(guo),你要(yao)(yao)下(xia)載一(yi)個(ge)Castle.Windsor.dll,它主要(yao)(yao)實現(xian)ioc功能的。
說干(gan)就干(gan),事情和前兩個組件的(de)工作(zuo)場(chang)景是(shi)相似(si)的(de),一個irepository,多(duo)種實現(xian)方(fang)式(shi),ef,linq,nhibernate,ado.net等等,你可以根據你的(de)需要去實現(xian)它,這只(zhi)是(shi)最(zui)大層次上(shang)的(de)多(duo)態,代(dai)碼(ma)可能是(shi)這樣:
泛型類版本
1 #region 泛型注入 2 public interface IRepository<T> 3 { 4 void Insert(T entity); 5 } 6 7 public class EFRepository<T> : IRepository<T> 8 { 9 #region IRepository<T> 成員 10 11 public void Insert(T entity) 12 { 13 Console.WriteLine("EFRepository泛型注(zhu)入" + entity); 14 } 15 16 #endregion 17 } 18 #endregion
非泛型版(ban)本(ben)(泛型方法版(ban)本(ben))
1 #region 非泛型注入 2 public interface IRepository 3 { 4 void Insert<T>(T entity); 5 } 6 7 public class EFRepository : IRepository 8 { 9 #region IRepository<T> 成員 10 11 public void Insert<T>(T entity) 12 { 13 Console.WriteLine("EFRepository非(fei)泛型注入" + entity); 14 } 15 16 #endregion 17 } 18 19 public class LINQRespository : IRepository 20 { 21 #region IRepository<T> 成員 22 23 public void Insert<T>(T entity) 24 { 25 Console.WriteLine("LINQRepository非(fei)泛型注入" + entity); 26 } 27 28 #endregion 29 } 30 #endregion
對于這(zhe)兩種(zhong)類(lei)型,在castle配置上(shang)也略有(you)不同,看代碼:
<component id="非泛型" service="Test.IRepository,Test" type="Test.EFRepository,Test" /> <component id="泛型" service="Test.IRepository`1,Test" type="Test.EFRepository`1,Test" />
上面的(de)(de)代(dai)(dai)碼是架構層次的(de)(de),而(er)對于具(ju)體(ti)的(de)(de)業(ye)務,如用戶方面的(de)(de)業(ye)務可(ke)(ke)能(neng)有多(duo)個版本的(de)(de)考慮,可(ke)(ke)能(neng)有代(dai)(dai)緩存的(de)(de),不代(dai)(dai)緩存的(de)(de),可(ke)(ke)能(neng)有發郵件的(de)(de),也(ye)可(ke)(ke)能(neng)有發短信的(de)(de),這是具(ju)體(ti)業(ye)務層次的(de)(de)多(duo)態,代(dai)(dai)碼可(ke)(ke)能(neng)是這樣的(de)(de):
1 #region 服務是泛型,類型不是泛型 2 3 public interface IMessageService<T> 4 { 5 void Sending(T entity); 6 } 7 public class UserService : IMessageService<User> 8 { 9 10 11 #region IMessageService<User> 成員 12 13 public void Sending(User entity) 14 { 15 Console.WriteLine("用(yong)(yong)戶模塊發(fa)消息,采用(yong)(yong)E-Mail方式"); 16 } 17 18 #endregion 19 } 20 21 public class ProductService : IMessageService<Product> 22 { 23 #region IMessageService<Product> 成員 24 25 public void Sending(Product entity) 26 { 27 Console.WriteLine("產品模塊(kuai)發(fa)消息采用短信"); 28 } 29 30 #endregion 31 } 32 #endregion
看上面的代(dai)碼,一(yi)個發(fa)消息(xi)的業務(wu),它對于不同的業務(wu)對象,可能有不同的實現(xian)方式(shi),而這種方法,我們可以在配(pei)置文(wen)件中進行設置:
1 <component id="具體業務,接口為泛型,實現(xian)非泛型" service="Test.IMessageService`1[[Test.User,Test]],Test"
type="Test.UserService,Test" />
整(zheng)個配置文(wen)件內(nei)容如下:
<configuration>
<configSections>
<section name="castle" type="Castle.Windsor.Configuration.AppDomain.CastleSectionHandler, Castle.Windsor"/>
</configSections>
<castle>
<components>
<component id="非(fei)泛型" service="Test.IRepository,Test" type="Test.EFRepository,Test" />
<component id="泛型" service="Test.IRepository`1,Test" type="Test.EFRepository`1,Test" />
<component id="具體業(ye)務,接口為泛(fan)型,實現(xian)非(fei)泛(fan)型" service="Test.IMessageService`1[[Test.User,Test]],Test" type="Test.UserService,Test" />
</components>
</castle>
</configuration>
而castle容器的代(dai)碼也封裝了一下(xia),改(gai)了上人的低(di)版本的,呵呵
/// <summary> /// IOC容器 /// </summary> public sealed class Container { #region Fields & Properies /// <summary> /// WindsorContainer object /// </summary> private WindsorContainer windsor; private IKernel kernel; public IKernel Kernel { get { return kernel; } } /// <summary> /// 容器實例 /// </summary> private static readonly Container instance = new Container(); public static Container Instance { get { return Container.instance; } } #endregion #region Constructors /// <summary> /// Constructor Method. /// Initialization IOC. /// </summary> public Container() { try { Castle.Core.Resource.ConfigResource source = new Castle.Core.Resource.ConfigResource(); XmlInterpreter interpreter = new XmlInterpreter(source); windsor = new WindsorContainer(interpreter); kernel = windsor.Kernel; } catch (Exception) { throw; } } #endregion #region Public Methods /// <summary> /// Returns a component instance by the type of service. /// </summary> /// <typeparam name="T"></typeparam> /// <returns></returns> public T Resolve<T>() { return kernel.Resolve<T>(); } /// <summary> /// Release resource that be container used. /// </summary> public void Dispose() { kernel.Dispose(); } #endregion #region Private Methods /// <summary> /// Returns a component instance by the service name. /// </summary> /// <param name="service"></param> /// <returns></returns> private object Resolve(Type service) { return kernel.Resolve(service); } /// <summary> /// Returns a component instance by the service name. /// </summary> /// <param name="key"></param> /// <returns></returns> private object Resolve(String key) { return kernel.Resolve<object>(key); } #endregion }
在程序中調(diao)用它的代(dai)碼(ma)為:
IRepository iRepository = Container.Instance.Resolve<IRepository>(); iRepository.Insert<User>(new User { Name = "ok" }); IRepository<User> iRepository1 = Container.Instance.Resolve<IRepository<User>>(); iRepository1.Insert(new User { Name = "ok" }); IMessageService<User> r = (IMessageService<User>)Container.Instance.Resolve<IMessageService<User>>(); r.Sending(new User { Name = "ok" });
運行的結果為:
感謝您的閱讀!