摘要:在Castle IOC容器实践之Startable Facility(一)中我们已经学会了如何去使用Startable Facility,本文将在此基础进一步对它的原理做一些分析。
在Castle IOC容器实践之Startable Facility(一)中我们已经看到了如何去使用Startable Facility,本文将对它的原理做一些分析。先看一下接口IStartable,它的实现代码如下:
public interface IStartable
{
void Start();![InBlock.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
void Stop();
} 代码是相当的简单,只有两个方法,分别在组件创建的时候和销毁的时候执行,这就涉及到了组件的生命周期管理。在 Windsor中,接口
ILifecycleConcern 提供特定的组件生命周期管理:
public interface ILifecycleConcern
{
void Apply( ComponentModel model, object component );![InBlock.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
} 现在我们要实现组件的自动创建和销毁,就需要实现接口
ILifecycleConcern ,在 Startable Facility 中分别用两个类来实现,第一个类StartConcern,它判断如果组件实现了接口IStartable,则直接调用它的Start()方法;如果组件是用特性startMethod,则获取并调用具有startMethod特性的方法:
public class StartConcern : ILifecycleConcern
{
private static readonly StartConcern _instance = new StartConcern();![InBlock.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
protected StartConcern()
{ ![InBlock.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
}![InBlock.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
public static StartConcern Instance
{
get { return _instance; }
}![InBlock.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
public void Apply(ComponentModel model, object component)
{
if (component is IStartable)
{
(component as IStartable).Start();
}
else if (model.Configuration != null)
{
String startMethod = model.Configuration.Attributes["startMethod"];
if (startMethod != null)
{ ![InBlock.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
MethodInfo method = model.Implementation.GetMethod(startMethod);![InBlock.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
method.Invoke(component, null);
}
}
}
} 第二个类是
StopConcern ,它判断如果组件实现了接口IStartable,则直接调用它的Stop()方法;如果组件是用特性stopMethod,则获取并调用具有stopMethod特性的方法:
public class StopConcern : ILifecycleConcern
{
private static readonly StopConcern _instance = new StopConcern();![InBlock.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
protected StopConcern()
{ ![InBlock.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
}![InBlock.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
public static StopConcern Instance
{
get { return _instance; }
}![InBlock.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
public void Apply(ComponentModel model, object component)
{
if(component is IStartable)
{
(component as IStartable).Stop();
}
else if (model.Configuration != null)
{
String stopMethod = model.Configuration.Attributes["stopMethod"];![InBlock.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
if (stopMethod != null)
{
MethodInfo method = model.Implementation.GetMethod(stopMethod);![InBlock.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
method.Invoke(component, null);
}
}
}
} 好了,知道了 Startable Facility如何管理组件的生命周期,我们就来看看真正的 Startable Facility是如何实现的。每一个 Facility都是满足这样的一个继承关系:
图1 Facility继承关系图 其中的Abstract Facility提供了一些默认的实现,Facility可以直接实现IFacility,也可以继承于Abstract Facility。IFacility的实现如下:
public interface IFacility
{
void Init(IKernel kernel, IConfiguration facilityConfig);![InBlock.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![InBlock.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
void Terminate();![InBlock.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
} 那么到底如何让组件满足依赖性后就自动执行呢?注意到再 Startable Facility的 Init()注册了这样的两个事件:
protected override void Init()
{
converter = (ITypeConverter) Kernel.GetSubSystem(SubSystemConstants.ConversionManagerKey);![InBlock.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![InBlock.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
Kernel.ComponentModelCreated += ![InBlock.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
new ComponentModelDelegate(OnComponentModelCreated);![InBlock.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
Kernel.ComponentRegistered += ![InBlock.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
new ComponentDataDelegate(OnComponentRegistered);![InBlock.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
} 分别为OnComponentModelCreated和OnComponentRegistered。当我们注册一个组件时首先会出发OnComponentRegistered事件,在它里面判断组件是否满足依赖性,如果不满足,则添加到一个等待列表中,否则就直接启动,然后再对这个等待列表进行检测,看添加改组件后,列表中是否有组件满足了依赖性:
private void OnComponentRegistered(String key, IHandler handler)
{
bool startable = (bool) handler.ComponentModel.ExtendedProperties["startable"];![InBlock.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
if (startable)
{
if (handler.CurrentState == HandlerState.WaitingDependency)
{
waitList.Add( handler );
}
else
{
Start( key );
}
}![InBlock.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
CheckWaitingList();
} ![None.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/None.gif)
private void CheckWaitingList()
{
IHandler[] handlers = (IHandler[]) waitList.ToArray( typeof(IHandler) );![InBlock.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
IList validList = new ArrayList();![InBlock.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
foreach(IHandler handler in handlers)
{
if (handler.CurrentState == HandlerState.Valid)
{
validList.Add(handler);![InBlock.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
waitList.Remove(handler);
}
}![InBlock.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
foreach(IHandler handler in validList)
{
Start( handler.ComponentModel.Name );
}
} 刚才说到,如果满足了依赖性,则会请求创建这个组件:
private void Start(String key)
{
object instance = Kernel[key];
} 这时就触发了 OnComponentModelCreated事件,这时就该用到开始我们所讲的那两生命周期处理的类了:
private void OnComponentModelCreated(ComponentModel model)
{
bool startable = ![InBlock.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
CheckIfComponentImplementsIStartable(model) || HasStartableAttributeSet(model);![InBlock.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
model.ExtendedProperties["startable"] = startable;![InBlock.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
if (startable)
{
model.LifecycleSteps.Add( ![InBlock.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
LifecycleStepType.Commission, StartConcern.Instance );![InBlock.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
model.LifecycleSteps.Add( ![InBlock.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
LifecycleStepType.Decommission, StopConcern.Instance );![InBlock.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
}
} 首先还是先判断组件是否实现了 IStartable接口或这时候有特性 startable,如果没有那也就不用自动启动了,否则就把 StartConcern和 StopConcern分别注册为组件的生命周期开始行为和生命周期结束行为,(关于组件的生命周期的详细内容可以参考我前面写的 Castle IOC容器组件生命周期管理)。此时组件进入生命周期开始,会调用 StartConcern的 Apply()方法,这时就触发组件的 Start()方法,同样在组件销毁时调用 StopConcern的 Apply()方法,这时就会调用组件的 Stop()方法。这样就完成整个了组件的自动执行与销毁的全过程。
本文转自lihuijun51CTO博客,原文链接: http://blog.51cto.com/terrylee/67685 ,如需转载请自行联系原作者