zoukankan      html  css  js  c++  java
  • Castle IOC容器实践之Startable Facility(二)

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

     

    主要内容

    Startable Facility原理分析

    ……

     

    Castle IOC容器实践之Startable Facility(一)中我们已经看到了如何去使用Startable Facility,本文将对它的原理做一些分析。先看一下接口IStartable,它的实现代码如下:

    public interface IStartable
    {
        
    void Start();

        
    void Stop();
    }


    代码是相当的简单,只有两个方法,分别在组件创建的时候和销毁的时候执行,这就涉及到了组件的生命周期管理。在Windsor中,接口ILifecycleConcern提供特定的组件生命周期管理:

    public interface ILifecycleConcern
    {
        
    void Apply( ComponentModel model, object component );

    }


    现在我们要实现组件的自动创建和销毁,就需要实现接口ILifecycleConcern,在Startable Facility中分别用两个类来实现,第一个类StartConcern,它判断如果组件实现了接口IStartable,则直接调用它的Start()方法;如果组件是用特性startMethod,则获取并调用具有startMethod特性的方法:

    public class StartConcern : ILifecycleConcern
    {
        
    private static readonly StartConcern _instance = new StartConcern();

        
    protected StartConcern()
        
    {

        }


        
    public static StartConcern Instance
        
    {
            
    get return _instance; }
        }


        
    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)
                
    {

                    MethodInfo method 
    = model.Implementation.GetMethod(startMethod);

                    method.Invoke(component, 
    null);
                }

            }

        }

    }


    第二个类是StopConcern,它判断如果组件实现了接口IStartable,则直接调用它的Stop()方法;如果组件是用特性stopMethod,则获取并调用具有stopMethod特性的方法:

    public class StopConcern : ILifecycleConcern
    {
        
    private static readonly StopConcern _instance = new StopConcern();

        
    protected StopConcern()
        
    {

        }


        
    public static StopConcern Instance
        
    {
            
    get return _instance; }
        }


        
    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"];

                
    if (stopMethod != null)
                
    {
                    MethodInfo method 
    = model.Implementation.GetMethod(stopMethod);

                    method.Invoke(component, 
    null);
                }

            }

        }

    }


    好了,知道了Startable Facility如何管理组件的生命周期,我们就来看看真正的Startable Facility是如何实现的。每一个Facility都是满足这样的一个继承关系:

    1 Facility继承关系图

    其中的Abstract Facility提供了一些默认的实现,Facility可以直接实现IFacility,也可以继承于Abstract FacilityIFacility的实现如下:

    public interface IFacility
    {
        
    void Init(IKernel kernel, IConfiguration facilityConfig);


        
    void Terminate();

    }


    那么到底如何让组件满足依赖性后就自动执行呢?注意到再Startable FacilityInit()注册了这样的两个事件:

    protected override void Init()
    {
        converter 
    = (ITypeConverter) Kernel.GetSubSystem(SubSystemConstants.ConversionManagerKey);


        Kernel.ComponentModelCreated 
    += 

            
    new ComponentModelDelegate(OnComponentModelCreated);

        Kernel.ComponentRegistered 
    += 

            
    new ComponentDataDelegate(OnComponentRegistered);

    }

     

    分别为OnComponentModelCreatedOnComponentRegistered。当我们注册一个组件时首先会出发OnComponentRegistered事件,在它里面判断组件是否满足依赖性,如果不满足,则添加到一个等待列表中,否则就直接启动,然后再对这个等待列表进行检测,看添加改组件后,列表中是否有组件满足了依赖性:

    private void OnComponentRegistered(String key, IHandler handler)
    {
        
    bool startable = (bool) handler.ComponentModel.ExtendedProperties["startable"];

        
    if (startable)
        
    {
            
    if (handler.CurrentState == HandlerState.WaitingDependency)
            
    {
                waitList.Add( handler );
            }

            
    else
            
    {
                Start( key );
            }

        }


        CheckWaitingList();
    }


    private void CheckWaitingList()
    {
        IHandler[] handlers 
    = (IHandler[]) waitList.ToArray( typeof(IHandler) );

        IList validList 
    = new ArrayList();

        
    foreach(IHandler handler in handlers)
        
    {
            
    if (handler.CurrentState == HandlerState.Valid)
            
    {
                validList.Add(handler);

                waitList.Remove(handler);
            }

        }


        
    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 = 

            CheckIfComponentImplementsIStartable(model) 
    || HasStartableAttributeSet(model);

        model.ExtendedProperties[
    "startable"= startable;

        
    if (startable)
        
    {
            model.LifecycleSteps.Add( 

                LifecycleStepType.Commission, StartConcern.Instance );

            model.LifecycleSteps.Add( 

                LifecycleStepType.Decommission, StopConcern.Instance );

        }

    }


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

     

    上篇:Castle IOC容器实践之Startable Facility

     

    参考资料

    Castle的官方网站http://www.castleproject.org

  • 相关阅读:
    oracle 随机函数
    cmd和dos的区别
    SAP HANA 常用函数
    编程语言发展史
    PL/SQL Job
    ETL工具总结
    JDK、JRE、JVM三者间的关系
    Redis过滤器如何与Envoy代理一起使用
    apache配置https
    kubernetes监控和性能分析工具:heapster+influxdb+grafana
  • 原文地址:https://www.cnblogs.com/Terrylee/p/399583.html
Copyright © 2011-2022 走看看