Castle最早在2003年誕生於Apache Avalon項目,目的是為了創建一個IOC(控制反轉)框架。發展到現在已經有4個組件了,分別是ActiveRecord(ORM組件)、Windsor(IOC組件)、DynamicProxy(動態代理組件)、MonoRail(Web MVC組件)。
這里我們要學習的是Windsor組件,Windsor是Castle提供的一個IOC框架。
使用之前,首先需要引用兩個DLL,分別是:Castle.Core 和 Castle.Windsor。
IOC(控制反轉)框架
為了演示,我們創建ILogger接口和對應的實現類ConsoleLogger
public interface ILogger { void Debug(string msg); }
public class ConsoleLogger : ILogger { public void Debug(string msg) { Console.WriteLine("Console Debug :" + msg); } }
現在我們可以對IOC容器進行配置(本篇只講代碼配置,XML的配置可以參考官方文檔:http://docs.castleproject.org/Windsor.XML-Registration-Reference.ashx),步驟只需要兩步:
第一步:創建安裝類,所有的安裝類必須繼承自IWindsorInstaller
public interface IWindsorInstaller { void Install(IWindsorContainer container, IConfigurationStore store); }
接口中定義的Install方法用於執行容器里具體類的注冊(將需要加入到容器控制的接口及對應的實現注冊到容器中)
public class MyInstaller : IWindsorInstaller { public void Install(IWindsorContainer container, IConfigurationStore store) { container.Register(Component.For<ILogger>().ImplementedBy<ConsoleLogger>().LifestyleSingleton()); // //CastleWindsor.IEntity是實現類所在的空間 // container.Register(Classes.FromThisAssembly().InNamespace("CastleWindsor.IEntity").WithService.DefaultInterfaces()); // //繼承兩個接口 // container.Register( // Component.For<IUserRepository, IRepository>() // .ImplementedBy<MyRepository>() // ); // //簡單工廠 // container // .Register( // Component.For<IMyService>() // .UsingFactoryMethod( // () => MyLegacyServiceFactory.CreateMyService()) // ); // //泛型配置 // container.Register( // Component.For(typeof(IRepository<>) // .ImplementedBy(typeof(NHRepository<>) // ); // //實體生命周期 // container.Register( // Component.For<IMyService>() // .ImplementedBy<MyServiceImpl>() // .LifeStyle.Transient // .Named("myservice.default") // ); // //取先注冊的 // container.Register( // Component.For<IMyService>().ImplementedBy<MyServiceImpl>(), // Component.For<IMyService>().ImplementedBy<OtherServiceImpl>() // ); // //強制取后注冊的 // container.Register( // Component.For<IMyService>().ImplementedBy<MyServiceImpl>(), // Component.For<IMyService>().Named("OtherServiceImpl").ImplementedBy<OtherServiceImpl>().IsDefault() // ); // //注冊已經存在的 // var customer = new CustomerImpl(); // container.Register( // Component.For<ICustomer>().Instance(customer) // ); } }
第二步:在容器初始化的時候加載安裝類
public class WindsorInit { private static WindsorContainer _container; public static WindsorContainer GetContainer() { if (_container == null) { _container = new WindsorContainer(); _container.Install( new MyInstaller() ); } return _container; } public void CloseContex() { _container.Dispose(); } }
客戶端在使用的時候進行如下調用:
ILogger logger = WindsorInit.GetContainer().Resolve<ILogger>(); logger.Debug("記錄日志");
在需要從容器中獲取特定類的時候,只需調用container.Resolve 即可獲取特定的實現類
AOP攔截器
AOP就是可以在一個已有的類方法中動態地嵌入代碼,可以通過預編譯方式和運行期動態代理實現在不修改源代碼的情況下給程序動態統一添加功能。前提必須是被切入的類是通過IOC容器來控制的。
Castle通過DynamicProxy來實現動態代理每一個切面方法均需要實現接口IInterceptor。
下面通過代碼的方式來學習下AOP,新建一個切入類
public class LoggingInterceptor : IInterceptor { public void Intercept(IInvocation invocation) { Console.WriteLine("方法前調用"); try { invocation.Proceed(); } catch (Exception) { Console.WriteLine("方法出錯調用"); throw; } finally { Console.WriteLine("方法最后調用"); } } }
即在原來的方法中加入TryCatch塊,並記錄日志。客戶端調用的時候只需要在類上加標簽:
[Interceptor(typeof(LoggingInterceptor))]
public class PersonAppService : IPersonAppService
{
public void CreatePerson(string name, int age)
{
// todo
}
}
前提是PersonAppService這個類是受Windsor IOC容器控制的。
這樣在PersonAppService每個方法外面均會套上TryCatch並記錄日志。