Castle.Windsor IOC/AOP的使用
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并记录日志。