Castle实践2-Startable Facility

这一节我们来分析Facility,作为Castle的可扩展单元,他是可以带有注入性的,也就是对组件来说,他可能“侵犯”组件本身。下面我们从官方提供的一个StartableFacility开始。
<?xml:namespace prefix = o />

先明白这个Facility的作用,也就是要达到的目的:使一个实现了Castle.Model.IStartable接口的程序在满足依赖性的时候,能够自我执行。

public   interface  IStartable
{
    
void  Start();       //  创建的时候执行
     void  Stop();        //  销毁的时候执行
}


首先我们来了解一下这个接口:ILifecycleConcern,这个接口带有一个方法:
public   interface  ILifecycleConcern
{
    
void  Apply( ComponentModel model,  object  component );
}


他用来在组件特定的生命周期提供处理行为。

比如,我们上一节提到的,实现了IInitializable接口的组件,容器会自动调用组件的初始化方法Initialize,只是执行这个接口的Facility是内置的(Kernel自带)。

接着,我们来用两个类实现这个接口:

第一个StartConcern,处理:如果是实现IStartable的组件则调用其Start()方法:

public   void  Apply(ComponentModel model,  object  component)
{
    (component 
as  IStartable).Start();
}


第二个StopConcern,处理:如果实现IStartable的组件则调用其Stop()方法:

public   void  Apply(ComponentModel model,  object  component)
{
    (component 
as  IStartable).Stop();
}


先别问为什么,知道功能就好,下面会继续讲到。

 

好了,我们看下如何实现一个Facility,创建一个自定的Facility可以直接实现IFacility接口,或者从AbstractFacility中继承下来,他们的不同支出只是AbstractFacility提供了IFacility接口的默认实现,你只需实现Init()方法即可。但其实IFacility包含的东西并不多,只有两个:

public   interface  IFacility
{
    
//  Facility被添加到容器中就立刻执行
     void  Init(IKernel kernel, IConfiguration facilityConfig);
    
//  一般在容器的Dispose()中被调用
     void  Terminate();
}


既然我们要达到程序的自启动,好自然,我们应该在组件加入容器的时候检查其依赖性满足后就启动他。那么如何让自定的Facility带有处理组件的能力呢?看下面的代码,在Facility加入容器时候,向容器注册了两个事件:

protected   override   void  Init()
{
    
//  在组件创建之后引发
    Kernel.ComponentModelCreated  +=   new  ComponentModelDelegate(OnComponentModelCreated);
    
//  在组件注册之后引发
    Kernel.ComponentRegistered  +=   new  ComponentDataDelegate(OnComponentRegistered);
}

所以,下面的事情就是这样发生的了:

Add一个组件,ComponentRegistered事件发生了。

OnComponentRegistered中检查依赖性,如果依赖性满足并组件实现了IStartable的话,则请求创建这个组件。

private   void  Start(String key)
{
    
object  instance  =  Kernel[key];
}


创建组件的时候,ComponentModelCreated引发,在ComponentModelCreated中加入生命周期的处理事件,这里就用到了本文开头的两个实现了ILifecycleConcern的类:StartConcernStopConcern

StartConcern注册为组件的LifecycleStepType.Commission(生命开始)周期处理行为。

StopConcern注册为组件的LifecycleStepType.Decommission(生命结束)周期处理行为。

组件被创建之后,立刻进入LifecycleStepType.Commission周期,StartConcern被触发处理,StartConcern.Apply()调用组件的Start()来达到自启动的目的。

同样组件从容器移除的时候,组件就进入LifecycleStepType.Decommission,那么StopConcern.Apply()触发组件的Stop()来进行“最后的喘息”。

StartableFacility设计原理已经说完,下步就实践咯。J

 

///   <summary>
///  这是一个实现IStartable的类,主要用Application.Run()启动一个窗口
///  注意看他的构造函数
///   </summary>
public   class  ApplicationRunner : IStartable
{
    
private  Form _form;
    
private  Thread _thread;

    
//  这里表明:这个类是依赖于类型为Form1的组件的
     public  ApplicationRunner(Form1 form)
    {
        _form 
=  form;
    }

    
#region  IStartable 成员

    
public   void  Start()
    {
        _thread 
=   new  Thread( new  ThreadStart(StartApp));
        _thread.Start();
    }

    
public   void  Stop()
    {
        MessageBox.Show(
" Stop is called, but it do nothing. " );
    }

    
#endregion

    
private   void  StartApp()
    {
        Application.Run( _form );
    }
}


其中Form1是一个普通窗口:

public   class  Form1 : System.Windows.Forms.Form
{
    
//  ….
}


最后是Main

[MTAThread]
static   void  Main()
{
     
//  建立容器
     IWindsorContainer container  =   new  WindsorContainer( " ../../AppConfig.xml " );

     
//  加入Facility
     container.AddFacility( " startable " new  StartableFacility());

     
//  加入一个ApplicationRunner,这时候容器检测到他对Form1有依赖,所以不启动
     container.AddComponent( " appRuner " typeof (ApplicationRunner));

     
//  加入Form1,此时ApplicationRunner满足依赖需求,Start就开始了
     container.AddComponent( " form1 " typeof (Form1));
}


OK
!这节就到这里,我想大家都清楚一个Facility的概念和用法了吧,有没有感觉到Facility的强大了?用他来@#$%*&组件吧,Bye~(下一节说点什么好呢?各位有建议吗?)

转载于:https://www.cnblogs.com/laiwen/archive/2005/09/07/231594.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值