Castle IOC容器构建配置详解(二)

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
简介:
摘要:在前一篇文章中我们并没有考虑配置的组件参数是什么类型,也没有在配置文件中指定过类型,那么Castle IOC是如何进行类型转换的?如何配置一些复杂的数据类型?如果有自定义的类型如何去进行类型转换?本文将进行一一解答这些问题。
              
主要内容
1 .基本类型配置
2 Array类型配置
3 List类型配置
4 Dictionary类型配置
5 .自定义类型转换
 
一.基本类型配置
Castle IOC的配置文件中,大家可能都已经注意一个问题了,就是不管组件接收的是什么基本数据类型,我们一律没有在配置文件中指定,也就是说,不管组件接收的类型是int型或者是String类型,我们都可以这样去配置:
None.gif < component  id ="MyComponent" >
None.gif
None.gif    
< parameters >
None.gif
None.gif        
< port > 10 </ port >
None.gif
None.gif    
</ parameters >
None.gif
None.gif
</ component >
这是因为在 Castle IOC中, MicroKernel中的 SubSystem中有一个 TypeConverter,它专门负责类型的转换。参数的注入一般都是通过构造函数或者公有的属性,基本数据类型在配置文件我们不需要用专门的节点去配置,但是对于一些复杂的数据类型久有些不一样。目前 Castle IOC能够支持的数据类型如下。
类型
节点
示例
System.Int32, Int16, Int64
-
< parameters >
< port > 10</port>
</ parameters >
System.UInt32, UInt16, UInt64
-
< parameters >
< port > 10</port>
</ parameters >
System.Char
-
< parameters >
    <letter>a</letter>
</ parameters >
System.Single, Double, Decimal
-
< parameters >
    <threshold>13.22</threshold>
</ parameters >
System.String
-
< parameters >
    <server>mail.host.com</server>
</ parameters >
System.Byte, SByte
-
< parameters >
    <rcolor>144</rcolor>
</ parameters >
System.Boolean
-
< parameters >
    <enabled>0</enabled>
</ parameters >
System.DateTime
-
< parameters >
    <initial>11022005</initial>
</ parameters >
System.Type
-
< parameters >
    <type>Components.MyComponent, Components</type>
</ parameters >
System.Array
array
参见后面
System.Collections.IList
list
参见后面
System.Collections.IDictionary
dictionary
参见后面
如果有其它的类型,我们需要编写自定义的TypeConverter
二.Array类型配置
组件构造函数有一个Array的参数
None.gif //  出处: [url]http://terrylee.cnblogs.com[/url]
None.gif
public   class  MyComponent
ExpandedBlockStart.gif
{
InBlock.gif    
private int[] orders;
InBlock.gif
InBlock.gif    
public int[]Orders
ExpandedSubBlockStart.gif    
{
InBlock.gif
ExpandedSubBlockStart.gif        
getreturn this.orders;}
ExpandedSubBlockEnd.gif    }

InBlock.gif    
public MyComponent()
ExpandedSubBlockStart.gif    
{
InBlock.gif
ExpandedSubBlockEnd.gif    }

InBlock.gif    
public MyComponent(int[]orders)
ExpandedSubBlockStart.gif    
{
InBlock.gif        
this.orders = orders;
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}
这时候我们的配置文件可以如下去写
None.gif <!-- 出处:[url]http://terrylee.cnblogs.com[/url] -->
None.gif
None.gif
<? xml version="1.0" encoding="utf-8"  ?>
None.gif
None.gif
< configuration >
None.gif
None.gif    
< component  id ="e"  type ="CastleDemo.MyComponent,CastleDemo" >
None.gif
None.gif        
< parameters >
None.gif
None.gif            
< Orders >
None.gif
None.gif                
< item  type ="System.Int32" >
None.gif
None.gif                    
< item > 1 </ item >
None.gif
None.gif                    
< item > 2 </ item >
None.gif
None.gif                    
< item > 3 </ item >
None.gif
None.gif                
</ item >
None.gif
None.gif            
</ Orders >
None.gif
None.gif        
</ parameters >
None.gif
None.gif    
</ component >
None.gif
None.gif
</ configuration >
三.List类型配置
组件构造函数有一个IList类型的参数
None.gif // 出处: [url]http://terrylee.cnblogs.com[/url]
None.gif
public   class  MyComponent
ExpandedBlockStart.gif
{
InBlock.gif    
private IList _hosts;
InBlock.gif
InBlock.gif    
public MyComponent(IList hosts)
ExpandedSubBlockStart.gif    
{
InBlock.gif        
this._hosts = hosts;
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    
public IList Hosts
ExpandedSubBlockStart.gif    
{
ExpandedSubBlockStart.gif        
get return _hosts; }
ExpandedSubBlockEnd.gif    }

InBlock.gif    
//dot.gifdot.gif
ExpandedBlockEnd.gif
}
这时候我们的配置文件应该如下
None.gif <!-- 出处:[url]http://terrylee.cnblogs.com[/url] -->
None.gif
None.gif
<? xml version="1.0" encoding="utf-8"  ?>
None.gif
None.gif
< configuration >
None.gif
None.gif    
< component  id ="mycomponent"  type ="CastleDemo.MyComponent,CastleDemo" >
None.gif
None.gif        
< parameters >
None.gif
None.gif            
< hosts >
None.gif
None.gif                
< list   type ="System.String" >
None.gif
None.gif                    
< item > server1 </ item >
None.gif
None.gif                    
< item > server2 </ item >
None.gif
None.gif                    
< item > server3 </ item >
None.gif
None.gif                    
< item > server4 </ item >
None.gif
None.gif                
</ list >
None.gif
None.gif            
</ hosts >
None.gif
None.gif        
</ parameters >
None.gif
None.gif    
</ component >
None.gif
None.gif
</ configuration >
四.Dictionary类型配置
组件构造函数有一个Idictionary类型的参数
None.gif // 出处: [url]http://terrylee.cnblogs.com[/url]
None.gif
public   class  MyComponent
ExpandedBlockStart.gif
{
InBlock.gif    
private IDictionary _dictionary;
InBlock.gif
InBlock.gif    
public MyComponent(IDictionary d)
ExpandedSubBlockStart.gif    
{
InBlock.gif        
this._dictionary = d;
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    
public IDictionary Dictionary
ExpandedSubBlockStart.gif    
{
ExpandedSubBlockStart.gif        
getreturn this._dictionary;}
ExpandedSubBlockEnd.gif    }

InBlock.gif    
//dot.gifdot.gif
ExpandedBlockEnd.gif
}
配置文件应该如下去写:
None.gif <!-- 出处:[url]http://terrylee.cnblogs.com[/url] -->
None.gif
None.gif
<? xml version="1.0" encoding="utf-8"  ?>
None.gif
None.gif
< configuration >
None.gif
None.gif    
< component  id ="MyComponent"  type ="CastleDemo.MyComponent,CastleDemo" >
None.gif
None.gif        
< parameters >
None.gif
None.gif            
< d >
None.gif
None.gif                
< dictionary >
None.gif
None.gif                    
< entry  key ="a" > a </ entry >
None.gif
None.gif                    
< entry  key ="b" > b </ entry >
None.gif
None.gif                    
< entry  key ="c" > c </ entry >
None.gif
None.gif                
</ dictionary >
None.gif
None.gif            
</ d >
None.gif
None.gif        
</ parameters >
None.gif
None.gif    
</ component >
None.gif
None.gif
</ configuration >
或者我们可以在配置文件中分别指定 KeyValue的数据类型,分别使用 keyTypevalueType
None.gif <!-- 出处:[url]http://terrylee.cnblogs.com[/url] -->
None.gif
None.gif
<? xml version="1.0" encoding="utf-8"  ?>
None.gif
None.gif
< configuration >
None.gif
None.gif    
< component  id ="MyComponent"  type ="CastleDemo.MyComponent,CastleDemo" >
None.gif
None.gif        
< parameters >
None.gif
None.gif            
< d >
None.gif
None.gif                
< dictionary  keyType ="System.String, mscorlib"  valueType ="System.String, mscorlib" >
None.gif
None.gif                    
< entry  key ="a" > a </ entry >
None.gif
None.gif                    
< entry  key ="b" > b </ entry >
None.gif
None.gif                    
< entry  key ="c" > c </ entry >
None.gif
None.gif                
</ dictionary >
None.gif
None.gif            
</ d >
None.gif
None.gif        
</ parameters >
None.gif
None.gif    
</ component >
None.gif
None.gif
</ configuration >

五.自定义类型转换
要实现我们自定义的类型转换,在这之前我们还是花一点时间来看看Castle IOC中是如何实现类型的转换的。在SubSystems中有一个Conversion,专门负责类型的转换,通过一个类型转换器 ConversionManager 来实现对类型转换的管理,在DefaultConversionManager初始化的时候,会加载以下几个类型转换:
None.gif protected   virtual   void  InitDefaultConverters()
ExpandedBlockStart.gif
{
InBlock.gif    Add( 
new PrimitiveConverter() );
InBlock.gif
InBlock.gif    Add( 
new TypeNameConverter() );
InBlock.gif
InBlock.gif    Add( 
new EnumConverter() );
InBlock.gif
InBlock.gif    Add( 
new ListConverter() );
InBlock.gif
InBlock.gif    Add( 
new DictionaryConverter() );
InBlock.gif
InBlock.gif    Add( 
new ArrayConverter() ); 
InBlock.gif
ExpandedBlockEnd.gif}
这些类型转换器之间的结构图如下:
1
PrimitiveConverter :负责基本数据类型的转换
TypeNameConverter :负责把一个类型的名字转换成这个类型的实例
EnumConverter :负责枚举类型的转换
ListConverter :负责Ilist数据类型的转换
DictionaryConverter :负责Idictionary数据类型转换
ArrayConverter :负责Array数据类型转换
以其中的 PrimitiveConverter 为例来看一下它的实现代码:
None.gif public   class  PrimitiveConverter : AbstractTypeConverter
ExpandedBlockStart.gif
{
InBlock.gif    
private Type[] types;
InBlock.gif
InBlock.gif    
public PrimitiveConverter()
ExpandedSubBlockStart.gif    
{
InBlock.gif        types 
= new Type[]
InBlock.gif
ExpandedSubBlockStart.gif            
{
InBlock.gif                
typeof (Char),
InBlock.gif
InBlock.gif                
typeof (DateTime),
InBlock.gif
InBlock.gif                
typeof (Decimal),
InBlock.gif
InBlock.gif                
typeof (Boolean),
InBlock.gif
InBlock.gif                
typeof (Int16),
InBlock.gif
InBlock.gif                
typeof (Int32),
InBlock.gif
InBlock.gif                
typeof (Int64),
InBlock.gif
InBlock.gif                
typeof (UInt16),
InBlock.gif
InBlock.gif                
typeof (UInt32),
InBlock.gif
InBlock.gif                
typeof (UInt64),
InBlock.gif
InBlock.gif                
typeof (Byte),
InBlock.gif
InBlock.gif                
typeof (SByte),
InBlock.gif
InBlock.gif                
typeof (Single),
InBlock.gif
InBlock.gif                
typeof (Double),
InBlock.gif
InBlock.gif                
typeof (String)
InBlock.gif
ExpandedSubBlockEnd.gif            }
;
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    
public override bool CanHandleType(Type type)
ExpandedSubBlockStart.gif    
{
InBlock.gif        
return Array.IndexOf(types, type) != -1;
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    
public override object PerformConversion(String value, Type targetType)
ExpandedSubBlockStart.gif    
{
InBlock.gif        
if (targetType == typeof(String)) return value;
InBlock.gif
InBlock.gif        
try
ExpandedSubBlockStart.gif        
{
InBlock.gif            
return Convert.ChangeType(value, targetType);
InBlock.gif
ExpandedSubBlockEnd.gif        }

InBlock.gif        
catch(Exception ex)
ExpandedSubBlockStart.gif        
{
InBlock.gif            String message 
= String.Format(
InBlock.gif
InBlock.gif                
"Could not convert from '{0}' to {1}"
InBlock.gif
InBlock.gif                value, targetType.FullName);
InBlock.gif
InBlock.gif            
throw new ConverterException(message, ex);
InBlock.gif
ExpandedSubBlockEnd.gif        }

InBlock.gif
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    
public override object PerformConversion(IConfiguration configuration, Type targetType)
InBlock.gif
ExpandedSubBlockStart.gif    
{
InBlock.gif
InBlock.gif        
return PerformConversion(configuration.Value, targetType);
InBlock.gif
ExpandedSubBlockEnd.gif    }

InBlock.gif
ExpandedBlockEnd.gif}
可以看到, Castle IOC会把所有的配置参数都当作 String类型接收,如果目标类型是 String,则直接返回结果,否则再进行类型转换。由此我们可以分析得出,要实现自己的类型转换,有以下两步:
1 .编写的自己的类型转换类,实现接口ITypeConverter
None.gif // 出处: [url]http://terrylee.cnblogs.com[/url]
None.gif
public   class  MyTypeConverter : ITypeConverter
ExpandedBlockStart.gif
{
InBlock.gif    
//dot.gifdot.gif
ExpandedBlockEnd.gif
}
2 .添加自己的类型转换到 ConversionManager
None.gif IKernel kernel  =   new  DefaultKernel();
None.gif
None.gifIConversionManager conversionMng 
=  (IConversionManager) 
None.gif
None.gif    kernel.GetSubSystem( SubSystemConstants.ConversionManagerKey );
None.gif
None.gifconversionMng.Add(
new  MyTypeConverter());
 
关于Castle IOC容器中构建配置信息就到这里了,我总共分为了一,二两部分来讲解。Castle IOC系列的文章后续还有很多,希望大家继续关注!










本文转自lihuijun51CTO博客,原文链接: http://blog.51cto.com/terrylee/67678  ,如需转载请自行联系原作者

相关文章
|
17天前
|
存储 安全 Linux
Podman入门全指南:安装、配置与运行容器
Podman入门全指南:安装、配置与运行容器
150 1
|
14天前
|
安全 持续交付 Docker
深入探索Dockerfile:构建容器化应用的秘密武器
深入探索Dockerfile:构建容器化应用的秘密武器
|
21天前
|
Kubernetes 负载均衡 开发者
构建高效后端服务:从微服务到容器化部署
【5月更文挑战第31天】本文深入探讨了现代后端开发中的关键概念,包括微服务的架构设计、容器化技术的运用以及它们如何共同提升应用的可扩展性、可靠性和性能。通过具体案例分析,我们将揭示这些技术是如何在实际开发中被实施的,并讨论它们对后端开发流程的影响。
|
22天前
|
运维 Kubernetes Devops
构建高效稳定的云基础设施:DevOps与容器化技术融合实践
【5月更文挑战第30天】 在当今快速迭代和持续交付的软件开发环境中,传统的IT运维模式已难以满足业务需求。本文深入探讨了如何通过DevOps理念和容器化技术的有机结合,构建一个既高效又稳定的云基础设施。文章首先概述了DevOps的核心概念和实施要点,然后详细介绍了容器化技术的优势及应用实践,最后通过案例分析展示了两者结合带来的显著效益。
43 3
|
22天前
|
运维 Kubernetes 持续交付
构建高效自动化运维体系:基于容器技术的持续集成与持续部署实践
【5月更文挑战第30天】随着云计算和微服务架构的兴起,传统的运维模式已难以满足快速迭代和高可用性的需求。本文探讨了如何利用容器技术构建一个高效、可靠的自动化运维体系,重点分析了Docker和Kubernetes在这一过程中的关键作用,并提出了一套基于这些技术的持续集成(CI)与持续部署(CD)解决方案。通过实际案例和操作步骤的详细阐述,文章为读者提供了一种实现自动化运维的有效途径,同时对未来运维技术的发展趋势进行了展望。
|
24天前
|
监控 Devops API
构建高效微服务架构:API网关的作用与实践构建高效稳定的云基础设施:DevOps与容器化技术融合实践
【5月更文挑战第28天】 在当今的软件开发领域,微服务架构因其灵活性、可扩展性和容错能力而备受推崇。本文将深入探讨API网关在构建微服务系统中的关键角色,包括它如何促进系统的高可用性、安全性和性能监控。我们将剖析API网关的核心组件,并借助具体实例展示如何实现一个高效的API网关来服务于复杂的微服务环境。 【5月更文挑战第28天】 随着企业数字化转型的深入,传统的IT运维模式已难以满足快速迭代和持续交付的需求。本文聚焦于如何通过融合DevOps理念与容器化技术来构建一个高效、稳定且可扩展的云基础设施。我们将探讨持续集成/持续部署(CI/CD)流程的优化、基于微服务架构的容器化部署以及自动化监
|
24天前
|
运维 Kubernetes jenkins
构建高效自动化运维系统:基于容器技术的持续集成与持续部署实践
【5月更文挑战第28天】 在现代软件工程实践中,持续集成(CI)和持续部署(CD)已成为提升开发效率、确保产品质量的关键环节。本文旨在探讨如何利用容器技术构建一套高效、可靠的自动化运维系统,以支持敏捷开发流程和微服务架构。通过对Docker容器及Kubernetes集群管理工具的深入分析,我们提出了一种结合Jenkins实现自动化测试、构建与部署的完整解决方案,并讨论了其在现实业务中的应用效果和面临的挑战。
|
14天前
|
安全 数据安全/隐私保护 Docker
Docker 容器连接:构建安全高效的容器化网络生态
Docker 容器连接:构建安全高效的容器化网络生态
|
16天前
|
监控 NoSQL Redis
Redis哨兵,Redis哨兵核心功能如何一个云服务器完成6个节点的搭建-docker什么是docker是否可以把六个容器,都写到同一个ym配置中,一次都启动,不就直接保证互通问题了吗?
Redis哨兵,Redis哨兵核心功能如何一个云服务器完成6个节点的搭建-docker什么是docker是否可以把六个容器,都写到同一个ym配置中,一次都启动,不就直接保证互通问题了吗?
|
21天前
|
敏捷开发 Kubernetes Cloud Native
构建高效云原生应用:容器化与微服务架构的融合
【5月更文挑战第31天】 随着云计算技术的不断演进,云原生应用已成为企业数字化转型的核心。本文深入探讨了如何通过容器化技术和微服务架构的有效结合,构建高效、弹性和可扩展的云原生应用。我们将分析容器化的基本概念、优势以及它如何促进微服务架构的实施,同时提供策略和最佳实践,帮助企业实现敏捷开发和持续部署,优化资源利用,并提高系统的可靠性。