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

    摘要:在Castle IOC容器实践之TypedFactory Facility(一)里面大家都已经知道了如何去使用TypedFactory Facility,也已经体会到它的方便之处了,为了更好的使用它,本篇我们对TypedFactory Facility的原理做一些简单的分析。

     

    主要内容

    TypedFactory Facility原理分析

    ……

     

    TypedFactory Facility中,有一个FactoryEntry类,这个类与我们平时项目开发中的实体类有一些类似,它用来记录工厂的相关信息,包括工厂的ID,工厂的接口,创建方法和销毁方法。这个类实现如下:

    public class FactoryEntry
    {
        
    private String _id;

        
    private Type _factoryInterface;

        
    private String _creationMethod;

        
    private String _destructionMethod;

        
    public FactoryEntry(String id, Type factoryInterface, String creationMethod, String destructionMethod)
        
    {
            
    // 省略了验证及异常处理

            _id 
    = id;

            _factoryInterface 
    = factoryInterface;

            _creationMethod 
    = creationMethod;

            _destructionMethod 
    = destructionMethod;
        }


        
    public String Id
        
    {
            
    get return _id; }
        }


        
    public Type FactoryInterface
        
    {
            
    get return _factoryInterface; }
        }


        
    public String CreationMethod
        
    {
            
    get return _creationMethod; }
        }


        
    public String DestructionMethod
        
    {
            
    get return _destructionMethod; }
        }

    }

    TypedFactoryFacility同样是继承于AbstractFacility,关于Facility的继承关系我在前面的文章中已经说过了。TypedFactory Facility在初始化的时候首先会获取工厂的类型,通过SubSystem来得到:

    protected override void Init()
    {
        Kernel.AddComponent( 
    "typed.fac.interceptor"typeof(FactoryInterceptor) );

        ITypeConverter converter 
    = (ITypeConverter)

            Kernel.GetSubSystem( SubSystemConstants.ConversionManagerKey );

        AddFactories(FacilityConfig, converter);
    }


    protected virtual void AddFactories(IConfiguration facilityConfig, ITypeConverter converter)
    {
        
    if (facilityConfig != null)
        
    {
            
    foreach(IConfiguration config in facilityConfig.Children["factories"].Children)
            
    {
                String id 
    = config.Attributes["id"];
                String creation 
    = config.Attributes["creation"];
                String destruction 
    = config.Attributes["destruction"];

                Type factoryType 
    = (Type)
                    converter.PerformConversion( config.Attributes[
    "interface"], typeof(Type) );

                
    try
                
    {
                    AddTypedFactoryEntry( 

                        
    new FactoryEntry(id, factoryType, creation, destruction) );
                }

                
    catch(Exception ex)
                
    {
                    
    throw new ConfigurationException("Invalid factory entry in configuration", ex);

                }

            }

        }

    }

    然后再创建一个FactoryEntry实例,记录了工厂的信息,放在了ComponentModel的扩展属性ExtendedProperties中,设置ComponentModel的生命周期为Singleton

    public void AddTypedFactoryEntry( FactoryEntry entry )
    {
        ComponentModel model 
    = 

            
    new ComponentModel(entry.Id, entry.FactoryInterface, typeof(Empty));

        model.LifestyleType 
    = LifestyleType.Singleton;

        model.ExtendedProperties[
    "typed.fac.entry"= entry;

        model.Interceptors.Add( 
    new InterceptorReference( typeof(FactoryInterceptor) ) );

        Kernel.AddCustomComponent( model );

    }

    在容器中加入一个工厂接口的拦截器FactoryInterceptor,当从容器中获取工厂时,会被拦截器拦截,拦截器的实现如下:

    [Transient]

    public class FactoryInterceptor : IMethodInterceptor, IOnBehalfAware
    {
        
    private FactoryEntry _entry;

        
    private IKernel _kernel;

        
    public FactoryInterceptor(IKernel kernel)
        
    {
            _kernel 
    = kernel;
        }


        
    public void SetInterceptedComponentModel(ComponentModel target)
        
    {
            _entry 
    = (FactoryEntry) target.ExtendedProperties["typed.fac.entry"];

        }


        
    public object Intercept(IMethodInvocation invocation, params object[] args)
        
    {
            String name 
    = invocation.Method.Name;

            
    if (name.Equals(_entry.CreationMethod))
            
    {
                
    if (args.Length == 0 || args[0== null)
                
    {
                    
    return _kernel[ invocation.Method.ReturnType ];

                }

                
    else
                
    {
                    
    return _kernel[ (String) args[0] ];
                }

            }


            
    else if (name.Equals(_entry.DestructionMethod))
            
    {
                
    if (args.Length == 1)
                
    {
                    _kernel.ReleaseComponent( args[
    0] );
                    
    return null;
                }

            }
            

            
    return invocation.Proceed(args);
        }

    }

    还有一点需要我们注意的是在上面实例化ComponentModel的时候用到了一个Empty类,这个类是一个空类,没有任何实现:

    public class Empty


    }

    在实例化ComponentModel时需要传入的几个参数是:

    public ComponentModel(String name, Type service, Type implementation)
    {
        
    this.name = name;

        
    this.service = service;

        
    this.implementation = implementation;

        
    this.lifestyleType = LifestyleType.Undefined;

    }

    即这里用一个空的类型来代替实现了的类型。

     

    上篇:Castle IOC容器实践之TypedFactory Facility(一)

     

    参考资料

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

  • 相关阅读:
    java 异常处理
    前端 网页宽高常用属性
    java 图片裁剪代码
    Eclipse常用设置
    SpringCloud Sleuth入门介绍
    Spring cloud stream【消息分区】
    Spring cloud stream【消息分组】
    Spring cloud stream【入门介绍】
    SpringCloud-分布式配置中心【加密-非对称加密】
    SpringCloud-分布式配置中心【加密-对称加密】
  • 原文地址:https://www.cnblogs.com/Terrylee/p/406721.html
Copyright © 2011-2022 走看看