博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Castle IOC容器实践之TypedFactory Facility(二)
阅读量:6243 次
发布时间:2019-06-22

本文共 3729 字,大约阅读时间需要 12 分钟。

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

 

主要内容

TypedFactory Facility
原理分析

……

 

TypedFactory Facility中,有一个
FactoryEntry
类,这个类与我们平时项目开发中的实体类有一些类似,它用来记录工厂的相关信息,包括工厂的ID,工厂的接口,创建方法和销毁方法。这个类实现如下:
None.gif
public
 
class
 FactoryEntry
ExpandedBlockStart.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.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.gif    
{
ExpandedSubBlockStart.gif        
get return _id; }
ExpandedSubBlockEnd.gif    }
InBlock.gif
InBlock.gif    
public Type FactoryInterface
ExpandedSubBlockStart.gif    
{
ExpandedSubBlockStart.gif        
get return _factoryInterface; }
ExpandedSubBlockEnd.gif    }
InBlock.gif
InBlock.gif    
public String CreationMethod
ExpandedSubBlockStart.gif    
{
ExpandedSubBlockStart.gif        
get return _creationMethod; }
ExpandedSubBlockEnd.gif    }
InBlock.gif
InBlock.gif    
public String DestructionMethod
ExpandedSubBlockStart.gif    
{
ExpandedSubBlockStart.gif        
get return _destructionMethod; }
ExpandedSubBlockEnd.gif    }
ExpandedBlockEnd.gif}
TypedFactoryFacility
同样是继承于AbstractFacility,关于Facility的继承关系我在前面的文章中已经说过了。TypedFactory Facility在初始化的时候首先会获取工厂的类型,通过SubSystem来得到:
None.gif
protected
 
override
 
void
 Init()
ExpandedBlockStart.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.gif
{
InBlock.gif    
if (facilityConfig != null)
ExpandedSubBlockStart.gif    
{
InBlock.gif        
foreach(IConfiguration config in facilityConfig.Children["factories"].Children)
ExpandedSubBlockStart.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.gif            
{
InBlock.gif                AddTypedFactoryEntry( 
InBlock.gif
InBlock.gif                    
new FactoryEntry(id, factoryType, creation, destruction) );
ExpandedSubBlockEnd.gif            }
InBlock.gif            
catch(Exception ex)
ExpandedSubBlockStart.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.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.gif
{
InBlock.gif    
private FactoryEntry _entry;
InBlock.gif
InBlock.gif    
private IKernel _kernel;
InBlock.gif
InBlock.gif    
public FactoryInterceptor(IKernel kernel)
ExpandedSubBlockStart.gif    
{
InBlock.gif        _kernel 
= kernel;
ExpandedSubBlockEnd.gif    }
InBlock.gif
InBlock.gif    
public void SetInterceptedComponentModel(ComponentModel target)
ExpandedSubBlockStart.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.gif    
{
InBlock.gif        String name 
= invocation.Method.Name;
InBlock.gif
InBlock.gif        
if (name.Equals(_entry.CreationMethod))
ExpandedSubBlockStart.gif        
{
InBlock.gif            
if (args.Length == 0 || args[0== null)
ExpandedSubBlockStart.gif            
{
InBlock.gif                
return _kernel[ invocation.Method.ReturnType ];
InBlock.gif
ExpandedSubBlockEnd.gif            }
InBlock.gif            
else
ExpandedSubBlockStart.gif            
{
InBlock.gif                
return _kernel[ (String) args[0] ];
ExpandedSubBlockEnd.gif            }
ExpandedSubBlockEnd.gif        }
InBlock.gif
InBlock.gif        
else if (name.Equals(_entry.DestructionMethod))
ExpandedSubBlockStart.gif        
{
InBlock.gif            
if (args.Length == 1)
ExpandedSubBlockStart.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.gif
InBlock.gif
ExpandedBlockEnd.gif}
在实例化 ComponentModel时需要传入的几个参数是:
None.gif
public
 ComponentModel(String name, Type service, Type implementation)
ExpandedBlockStart.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}
即这里用一个空的类型来代替实现了的类型。
本文转自lihuijun51CTO博客,原文链接:http://blog.51cto.com/terrylee/67689
 ,如需转载请自行联系原作者
你可能感兴趣的文章
awk工具
查看>>
设计模式-代理模式(Proxy)
查看>>
Windows Sharepoint services 3.0部署体验
查看>>
[分享] Mac 键盘和Pc键盘对照表
查看>>
windows下批量杀死进程
查看>>
第七章:面向对象(三)
查看>>
android-ripple-background
查看>>
我的友情链接
查看>>
编译安装Apache服务要点
查看>>
Arrays.copy()和ArrayList.clone()
查看>>
mosquitto安装、配置、测试、paho.mqtt-spy安装
查看>>
我的友情链接
查看>>
Eclispe 安装插件 Properties Editor
查看>>
ReactiveCocoa RACDelegateProxy
查看>>
网站架构案例精解
查看>>
iOS提示框,为什么你应该使用 MBProgressHUD?
查看>>
思科GLC-T、GLC-TE与SFP-GE-T电模块的区别
查看>>
Spring AOP 的 afterReturing 为什么不能改变返回值
查看>>
在Oracle RAC环境下创建数据库时提示不能验证ASMSNMP密码问题的解决(ORA-01017)
查看>>
集中管理:领导者,不能不考虑的几件事之—— 多维管理视角,一个都不能少...
查看>>