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

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

 

主要内容

TypedFactory Facility原理分析

……

 

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

None.gif public   class  FactoryEntry
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
private String _id;
InBlock.gif
InBlock.gif    
private Type _factoryInterface;
InBlock.gif
InBlock.gif    
private String _creationMethod;
InBlock.gif
InBlock.gif    
private String _destructionMethod;
InBlock.gif
InBlock.gif    
public FactoryEntry(String id, Type factoryInterface, String creationMethod, String destructionMethod)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
// dot.gifdot.gif省略了验证及异常处理
InBlock.gif

InBlock.gif        _id 
= id;
InBlock.gif
InBlock.gif        _factoryInterface 
= factoryInterface;
InBlock.gif
InBlock.gif        _creationMethod 
= creationMethod;
InBlock.gif
InBlock.gif        _destructionMethod 
= destructionMethod;
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    
public String Id
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif        
get dot.gifreturn _id; }
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    
public Type FactoryInterface
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif        
get dot.gifreturn _factoryInterface; }
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    
public String CreationMethod
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif        
get dot.gifreturn _creationMethod; }
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    
public String DestructionMethod
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif        
get dot.gifreturn _destructionMethod; }
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

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

None.gif protected   override   void  Init()
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    Kernel.AddComponent( 
"typed.fac.interceptor"typeof(FactoryInterceptor) );
InBlock.gif
InBlock.gif    ITypeConverter converter 
= (ITypeConverter)
InBlock.gif
InBlock.gif        Kernel.GetSubSystem( SubSystemConstants.ConversionManagerKey );
InBlock.gif
InBlock.gif    AddFactories(FacilityConfig, converter);
ExpandedBlockEnd.gif}

None.gif
None.gif
protected   virtual   void  AddFactories(IConfiguration facilityConfig, ITypeConverter converter)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
if (facilityConfig != null)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
foreach(IConfiguration config in facilityConfig.Children["factories"].Children)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            String id 
= config.Attributes["id"];
InBlock.gif            String creation 
= config.Attributes["creation"];
InBlock.gif            String destruction 
= config.Attributes["destruction"];
InBlock.gif
InBlock.gif            Type factoryType 
= (Type)
InBlock.gif                converter.PerformConversion( config.Attributes[
"interface"], typeof(Type) );
InBlock.gif
InBlock.gif            
try
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                AddTypedFactoryEntry( 
InBlock.gif
InBlock.gif                    
new FactoryEntry(id, factoryType, creation, destruction) );
ExpandedSubBlockEnd.gif            }

InBlock.gif            
catch(Exception ex)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
throw new ConfigurationException("Invalid factory entry in configuration", ex);
InBlock.gif
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

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

None.gif public   void  AddTypedFactoryEntry( FactoryEntry entry )
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    ComponentModel model 
= 
InBlock.gif
InBlock.gif        
new ComponentModel(entry.Id, entry.FactoryInterface, typeof(Empty));
InBlock.gif
InBlock.gif    model.LifestyleType 
= LifestyleType.Singleton;
InBlock.gif
InBlock.gif    model.ExtendedProperties[
"typed.fac.entry"= entry;
InBlock.gif
InBlock.gif    model.Interceptors.Add( 
new InterceptorReference( typeof(FactoryInterceptor) ) );
InBlock.gif
InBlock.gif    Kernel.AddCustomComponent( model );
InBlock.gif
ExpandedBlockEnd.gif}

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

None.gif [Transient]
None.gif
None.gif
public   class  FactoryInterceptor : IMethodInterceptor, IOnBehalfAware
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
private FactoryEntry _entry;
InBlock.gif
InBlock.gif    
private IKernel _kernel;
InBlock.gif
InBlock.gif    
public FactoryInterceptor(IKernel kernel)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        _kernel 
= kernel;
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    
public void SetInterceptedComponentModel(ComponentModel target)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        _entry 
= (FactoryEntry) target.ExtendedProperties["typed.fac.entry"];
InBlock.gif
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    
public object Intercept(IMethodInvocation invocation, params object[] args)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        String name 
= invocation.Method.Name;
InBlock.gif
InBlock.gif        
if (name.Equals(_entry.CreationMethod))
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
if (args.Length == 0 || args[0== null)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
return _kernel[ invocation.Method.ReturnType ];
InBlock.gif
ExpandedSubBlockEnd.gif            }

InBlock.gif            
else
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
return _kernel[ (String) args[0] ];
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
else if (name.Equals(_entry.DestructionMethod))
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
if (args.Length == 1)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                _kernel.ReleaseComponent( args[
0] );
InBlock.gif                
return null;
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }
        
InBlock.gif
InBlock.gif        
return invocation.Proceed(args);
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

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

None.gif public   class  Empty
ExpandedBlockStart.gifContractedBlock.gif
dot.gif
InBlock.gif
ExpandedBlockEnd.gif}

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

None.gif public  ComponentModel(String name, Type service, Type implementation)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
this.name = name;
InBlock.gif
InBlock.gif    
this.service = service;
InBlock.gif
InBlock.gif    
this.implementation = implementation;
InBlock.gif
InBlock.gif    
this.lifestyleType = LifestyleType.Undefined;
InBlock.gif
ExpandedBlockEnd.gif}

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

 

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

 

参考资料

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

转载于:https://www.cnblogs.com/Terrylee/archive/2006/05/23/406721.html

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值