且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Castle IOC容器实践之Startable Facility(二)

更新时间:2022-09-13 19:44:50



摘要:在Castle IOC容器实践之Startable Facility(一)中我们已经学会了如何去使用Startable Facility,本文将在此基础进一步对它的原理做一些分析。

 
主要内容
Startable Facility原理分析
……
 
Castle IOC容器实践之Startable Facility(一)中我们已经看到了如何去使用Startable Facility,本文将对它的原理做一些分析。先看一下接口IStartable,它的实现代码如下:
Castle IOC容器实践之Startable Facility(二)public interface IStartable
Castle IOC容器实践之Startable Facility(二)
{
Castle IOC容器实践之Startable Facility(二)    
void Start();
Castle IOC容器实践之Startable Facility(二)
Castle IOC容器实践之Startable Facility(二)    
void Stop();
Castle IOC容器实践之Startable Facility(二)}

代码是相当的简单,只有两个方法,分别在组件创建的时候和销毁的时候执行,这就涉及到了组件的生命周期管理。在Windsor中,接口ILifecycleConcern提供特定的组件生命周期管理:
Castle IOC容器实践之Startable Facility(二)public interface ILifecycleConcern
Castle IOC容器实践之Startable Facility(二)
{
Castle IOC容器实践之Startable Facility(二)    
void Apply( ComponentModel model, object component );
Castle IOC容器实践之Startable Facility(二)
Castle IOC容器实践之Startable Facility(二)}

现在我们要实现组件的自动创建和销毁,就需要实现接口ILifecycleConcern,在Startable Facility中分别用两个类来实现,第一个类StartConcern,它判断如果组件实现了接口IStartable,则直接调用它的Start()方法;如果组件是用特性startMethod,则获取并调用具有startMethod特性的方法:
Castle IOC容器实践之Startable Facility(二)public class StartConcern : ILifecycleConcern
Castle IOC容器实践之Startable Facility(二)
{
Castle IOC容器实践之Startable Facility(二)    
private static readonly StartConcern _instance = new StartConcern();
Castle IOC容器实践之Startable Facility(二)
Castle IOC容器实践之Startable Facility(二)    
protected StartConcern()
Castle IOC容器实践之Startable Facility(二)    
{
Castle IOC容器实践之Startable Facility(二)
Castle IOC容器实践之Startable Facility(二)    }

Castle IOC容器实践之Startable Facility(二)
Castle IOC容器实践之Startable Facility(二)    
public static StartConcern Instance
Castle IOC容器实践之Startable Facility(二)    
{
Castle IOC容器实践之Startable Facility(二)        
get return _instance; }
Castle IOC容器实践之Startable Facility(二)    }

Castle IOC容器实践之Startable Facility(二)
Castle IOC容器实践之Startable Facility(二)    
public void Apply(ComponentModel model, object component)
Castle IOC容器实践之Startable Facility(二)    
{
Castle IOC容器实践之Startable Facility(二)        
if (component is IStartable)
Castle IOC容器实践之Startable Facility(二)        
{
Castle IOC容器实践之Startable Facility(二)            (component 
as IStartable).Start();
Castle IOC容器实践之Startable Facility(二)        }

Castle IOC容器实践之Startable Facility(二)        
else if (model.Configuration != null)
Castle IOC容器实践之Startable Facility(二)        
{
Castle IOC容器实践之Startable Facility(二)            String startMethod 
= model.Configuration.Attributes["startMethod"];
Castle IOC容器实践之Startable Facility(二) 
Castle IOC容器实践之Startable Facility(二)            
if (startMethod != null)
Castle IOC容器实践之Startable Facility(二)            
{
Castle IOC容器实践之Startable Facility(二)
Castle IOC容器实践之Startable Facility(二)                MethodInfo method 
= model.Implementation.GetMethod(startMethod);
Castle IOC容器实践之Startable Facility(二)
Castle IOC容器实践之Startable Facility(二)                method.Invoke(component, 
null);
Castle IOC容器实践之Startable Facility(二)            }

Castle IOC容器实践之Startable Facility(二)        }

Castle IOC容器实践之Startable Facility(二)    }

Castle IOC容器实践之Startable Facility(二)}

第二个类是StopConcern,它判断如果组件实现了接口IStartable,则直接调用它的Stop()方法;如果组件是用特性stopMethod,则获取并调用具有stopMethod特性的方法:
Castle IOC容器实践之Startable Facility(二)public class StopConcern : ILifecycleConcern
Castle IOC容器实践之Startable Facility(二)
{
Castle IOC容器实践之Startable Facility(二)    
private static readonly StopConcern _instance = new StopConcern();
Castle IOC容器实践之Startable Facility(二)
Castle IOC容器实践之Startable Facility(二)    
protected StopConcern()
Castle IOC容器实践之Startable Facility(二)    
{
Castle IOC容器实践之Startable Facility(二)
Castle IOC容器实践之Startable Facility(二)    }

Castle IOC容器实践之Startable Facility(二)
Castle IOC容器实践之Startable Facility(二)    
public static StopConcern Instance
Castle IOC容器实践之Startable Facility(二)    
{
Castle IOC容器实践之Startable Facility(二)        
get return _instance; }
Castle IOC容器实践之Startable Facility(二)    }

Castle IOC容器实践之Startable Facility(二)
Castle IOC容器实践之Startable Facility(二)    
public void Apply(ComponentModel model, object component)
Castle IOC容器实践之Startable Facility(二)    
{
Castle IOC容器实践之Startable Facility(二)        
if(component is IStartable)
Castle IOC容器实践之Startable Facility(二)        
{
Castle IOC容器实践之Startable Facility(二)            (component 
as IStartable).Stop();
Castle IOC容器实践之Startable Facility(二)        }

Castle IOC容器实践之Startable Facility(二)        
else if (model.Configuration != null)
Castle IOC容器实践之Startable Facility(二)        
{
Castle IOC容器实践之Startable Facility(二)            String stopMethod 
= model.Configuration.Attributes["stopMethod"];
Castle IOC容器实践之Startable Facility(二)
Castle IOC容器实践之Startable Facility(二)            
if (stopMethod != null)
Castle IOC容器实践之Startable Facility(二)            
{
Castle IOC容器实践之Startable Facility(二)                MethodInfo method 
= model.Implementation.GetMethod(stopMethod);
Castle IOC容器实践之Startable Facility(二)
Castle IOC容器实践之Startable Facility(二)                method.Invoke(component, 
null);
Castle IOC容器实践之Startable Facility(二)            }

Castle IOC容器实践之Startable Facility(二)        }

Castle IOC容器实践之Startable Facility(二)    }

Castle IOC容器实践之Startable Facility(二)}

好了,知道了Startable Facility如何管理组件的生命周期,我们就来看看真正的Startable Facility是如何实现的。每一个Facility都是满足这样的一个继承关系:
Castle IOC容器实践之Startable Facility(二)1 Facility继承关系图
其中的Abstract Facility提供了一些默认的实现,Facility可以直接实现IFacility,也可以继承于Abstract FacilityIFacility的实现如下:
Castle IOC容器实践之Startable Facility(二)public interface IFacility
Castle IOC容器实践之Startable Facility(二)
{
Castle IOC容器实践之Startable Facility(二)    
void Init(IKernel kernel, IConfiguration facilityConfig);
Castle IOC容器实践之Startable Facility(二)
Castle IOC容器实践之Startable Facility(二)
Castle IOC容器实践之Startable Facility(二)    
void Terminate();
Castle IOC容器实践之Startable Facility(二)
Castle IOC容器实践之Startable Facility(二)}

那么到底如何让组件满足依赖性后就自动执行呢?注意到再Startable FacilityInit()注册了这样的两个事件:
Castle IOC容器实践之Startable Facility(二)protected override void Init()
Castle IOC容器实践之Startable Facility(二)
{
Castle IOC容器实践之Startable Facility(二)    converter 
= (ITypeConverter) Kernel.GetSubSystem(SubSystemConstants.ConversionManagerKey);
Castle IOC容器实践之Startable Facility(二)
Castle IOC容器实践之Startable Facility(二)
Castle IOC容器实践之Startable Facility(二)    Kernel.ComponentModelCreated 
+= 
Castle IOC容器实践之Startable Facility(二)
Castle IOC容器实践之Startable Facility(二)        
new ComponentModelDelegate(OnComponentModelCreated);
Castle IOC容器实践之Startable Facility(二)
Castle IOC容器实践之Startable Facility(二)    Kernel.ComponentRegistered 
+= 
Castle IOC容器实践之Startable Facility(二)
Castle IOC容器实践之Startable Facility(二)        
new ComponentDataDelegate(OnComponentRegistered);
Castle IOC容器实践之Startable Facility(二)
Castle IOC容器实践之Startable Facility(二)}
 
分别为OnComponentModelCreatedOnComponentRegistered。当我们注册一个组件时首先会出发OnComponentRegistered事件,在它里面判断组件是否满足依赖性,如果不满足,则添加到一个等待列表中,否则就直接启动,然后再对这个等待列表进行检测,看添加改组件后,列表中是否有组件满足了依赖性:
Castle IOC容器实践之Startable Facility(二)private void OnComponentRegistered(String key, IHandler handler)
Castle IOC容器实践之Startable Facility(二)
{
Castle IOC容器实践之Startable Facility(二)    
bool startable = (bool) handler.ComponentModel.ExtendedProperties["startable"];
Castle IOC容器实践之Startable Facility(二)
Castle IOC容器实践之Startable Facility(二)    
if (startable)
Castle IOC容器实践之Startable Facility(二)    
{
Castle IOC容器实践之Startable Facility(二)        
if (handler.CurrentState == HandlerState.WaitingDependency)
Castle IOC容器实践之Startable Facility(二)        
{
Castle IOC容器实践之Startable Facility(二)            waitList.Add( handler );
Castle IOC容器实践之Startable Facility(二)        }

Castle IOC容器实践之Startable Facility(二)        
else
Castle IOC容器实践之Startable Facility(二)        
{
Castle IOC容器实践之Startable Facility(二)            Start( key );
Castle IOC容器实践之Startable Facility(二)        }

Castle IOC容器实践之Startable Facility(二)    }

Castle IOC容器实践之Startable Facility(二)
Castle IOC容器实践之Startable Facility(二)    CheckWaitingList();
Castle IOC容器实践之Startable Facility(二)}

Castle IOC容器实践之Startable Facility(二)
Castle IOC容器实践之Startable Facility(二)
private void CheckWaitingList()
Castle IOC容器实践之Startable Facility(二)
{
Castle IOC容器实践之Startable Facility(二)    IHandler[] handlers 
= (IHandler[]) waitList.ToArray( typeof(IHandler) );
Castle IOC容器实践之Startable Facility(二)
Castle IOC容器实践之Startable Facility(二)    IList validList 
= new ArrayList();
Castle IOC容器实践之Startable Facility(二)
Castle IOC容器实践之Startable Facility(二)    
foreach(IHandler handler in handlers)
Castle IOC容器实践之Startable Facility(二)    
{
Castle IOC容器实践之Startable Facility(二)        
if (handler.CurrentState == HandlerState.Valid)
Castle IOC容器实践之Startable Facility(二)        
{
Castle IOC容器实践之Startable Facility(二)            validList.Add(handler);
Castle IOC容器实践之Startable Facility(二)
Castle IOC容器实践之Startable Facility(二)            waitList.Remove(handler);
Castle IOC容器实践之Startable Facility(二)        }

Castle IOC容器实践之Startable Facility(二)    }

Castle IOC容器实践之Startable Facility(二)
Castle IOC容器实践之Startable Facility(二)    
foreach(IHandler handler in validList)
Castle IOC容器实践之Startable Facility(二)    
{
Castle IOC容器实践之Startable Facility(二)        Start( handler.ComponentModel.Name );
Castle IOC容器实践之Startable Facility(二)    }

Castle IOC容器实践之Startable Facility(二)}

刚才说到,如果满足了依赖性,则会请求创建这个组件:
Castle IOC容器实践之Startable Facility(二)private void Start(String key)
Castle IOC容器实践之Startable Facility(二)
{
Castle IOC容器实践之Startable Facility(二)    
object instance = Kernel[key];
Castle IOC容器实践之Startable Facility(二)}

这时就触发了OnComponentModelCreated事件,这时就该用到开始我们所讲的那两生命周期处理的类了:
Castle IOC容器实践之Startable Facility(二)private void OnComponentModelCreated(ComponentModel model)
Castle IOC容器实践之Startable Facility(二)
{
Castle IOC容器实践之Startable Facility(二)    
bool startable = 
Castle IOC容器实践之Startable Facility(二)
Castle IOC容器实践之Startable Facility(二)        CheckIfComponentImplementsIStartable(model) 
|| HasStartableAttributeSet(model);
Castle IOC容器实践之Startable Facility(二)
Castle IOC容器实践之Startable Facility(二)    model.ExtendedProperties[
"startable"= startable;
Castle IOC容器实践之Startable Facility(二)
Castle IOC容器实践之Startable Facility(二)    
if (startable)
Castle IOC容器实践之Startable Facility(二)    
{
Castle IOC容器实践之Startable Facility(二)        model.LifecycleSteps.Add( 
Castle IOC容器实践之Startable Facility(二)
Castle IOC容器实践之Startable Facility(二)            LifecycleStepType.Commission, StartConcern.Instance );
Castle IOC容器实践之Startable Facility(二)
Castle IOC容器实践之Startable Facility(二)        model.LifecycleSteps.Add( 
Castle IOC容器实践之Startable Facility(二)
Castle IOC容器实践之Startable Facility(二)            LifecycleStepType.Decommission, StopConcern.Instance );
Castle IOC容器实践之Startable Facility(二)
Castle IOC容器实践之Startable Facility(二)    }

Castle IOC容器实践之Startable Facility(二)}

首先还是先判断组件是否实现了IStartable接口或这时候有特性startable,如果没有那也就不用自动启动了,否则就把StartConcernStopConcern分别注册为组件的生命周期开始行为和生命周期结束行为,(关于组件的生命周期的详细内容可以参考我前面写的Castle IOC容器组件生命周期管理)。此时组件进入生命周期开始,会调用StartConcernApply()方法,这时就触发组件的Start()方法,同样在组件销毁时调用StopConcernApply()方法,这时就会调用组件的Stop()方法。这样就完成整个了组件的自动执行与销毁的全过程。















本文转自lihuijun51CTO博客,原文链接: http://blog.51cto.com/terrylee/67685,如需转载请自行联系原作者