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

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
简介:
摘要:在前一篇文章中我们并没有考虑配置的组件参数是什么类型,也没有在配置文件中指定过类型,那么Castle IOC是如何进行类型转换的?如何配置一些复杂的数据类型?如果有自定义的类型如何去进行类型转换?本文将进行一一解答这些问题。
              
主要内容
1 .基本类型配置
2 Array类型配置
3 List类型配置
4 Dictionary类型配置
5 .自定义类型转换
 
一.基本类型配置
Castle IOC的配置文件中,大家可能都已经注意一个问题了,就是不管组件接收的是什么基本数据类型,我们一律没有在配置文件中指定,也就是说,不管组件接收的类型是int型或者是String类型,我们都可以这样去配置:
< component  id ="MyComponent" >

    
< parameters >

        
< port > 10 </ port >

    
</ parameters >

</ 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的参数
//  出处: [url]http://terrylee.cnblogs.com[/url]
public   class  MyComponent
{
    
private int[] orders;

    
public int[]Orders
    
{

        
getreturn this.orders;}
    }

    
public MyComponent()
    
{

    }

    
public MyComponent(int[]orders)
    
{
        
this.orders = orders;
    }

}
这时候我们的配置文件可以如下去写
<!-- 出处:[url]http://terrylee.cnblogs.com[/url] -->

<? xml version="1.0" encoding="utf-8"  ?>

< configuration >

    
< component  id ="e"  type ="CastleDemo.MyComponent,CastleDemo" >

        
< parameters >

            
< Orders >

                
< item  type ="System.Int32" >

                    
< item > 1 </ item >

                    
< item > 2 </ item >

                    
< item > 3 </ item >

                
</ item >

            
</ Orders >

        
</ parameters >

    
</ component >

</ configuration >
三.List类型配置
组件构造函数有一个IList类型的参数
// 出处: [url]http://terrylee.cnblogs.com[/url]
public   class  MyComponent
{
    
private IList _hosts;

    
public MyComponent(IList hosts)
    
{
        
this._hosts = hosts;
    }


    
public IList Hosts
    
{
        
get return _hosts; }
    }

    
//
}
这时候我们的配置文件应该如下
<!-- 出处:[url]http://terrylee.cnblogs.com[/url] -->

<? xml version="1.0" encoding="utf-8"  ?>

< configuration >

    
< component  id ="mycomponent"  type ="CastleDemo.MyComponent,CastleDemo" >

        
< parameters >

            
< hosts >

                
< list   type ="System.String" >

                    
< item > server1 </ item >

                    
< item > server2 </ item >

                    
< item > server3 </ item >

                    
< item > server4 </ item >

                
</ list >

            
</ hosts >

        
</ parameters >

    
</ component >

</ configuration >
四.Dictionary类型配置
组件构造函数有一个Idictionary类型的参数
// 出处: [url]http://terrylee.cnblogs.com[/url]
public   class  MyComponent
{
    
private IDictionary _dictionary;

    
public MyComponent(IDictionary d)
    
{
        
this._dictionary = d;
    }


    
public IDictionary Dictionary
    
{
        
getreturn this._dictionary;}
    }

    
//
}
配置文件应该如下去写:
<!-- 出处:[url]http://terrylee.cnblogs.com[/url] -->

<? xml version="1.0" encoding="utf-8"  ?>

< configuration >

    
< component  id ="MyComponent"  type ="CastleDemo.MyComponent,CastleDemo" >

        
< parameters >

            
< d >

                
< dictionary >

                    
< entry  key ="a" > a </ entry >

                    
< entry  key ="b" > b </ entry >

                    
< entry  key ="c" > c </ entry >

                
</ dictionary >

            
</ d >

        
</ parameters >

    
</ component >

</ configuration >
或者我们可以在配置文件中分别指定 KeyValue的数据类型,分别使用 keyTypevalueType
<!-- 出处:[url]http://terrylee.cnblogs.com[/url] -->

<? xml version="1.0" encoding="utf-8"  ?>

< configuration >

    
< component  id ="MyComponent"  type ="CastleDemo.MyComponent,CastleDemo" >

        
< parameters >

            
< d >

                
< dictionary  keyType ="System.String, mscorlib"  valueType ="System.String, mscorlib" >

                    
< entry  key ="a" > a </ entry >

                    
< entry  key ="b" > b </ entry >

                    
< entry  key ="c" > c </ entry >

                
</ dictionary >

            
</ d >

        
</ parameters >

    
</ component >

</ configuration >

五.自定义类型转换
要实现我们自定义的类型转换,在这之前我们还是花一点时间来看看Castle IOC中是如何实现类型的转换的。在SubSystems中有一个Conversion,专门负责类型的转换,通过一个类型转换器 ConversionManager 来实现对类型转换的管理,在DefaultConversionManager初始化的时候,会加载以下几个类型转换:
protected   virtual   void  InitDefaultConverters()
{
    Add( 
new PrimitiveConverter() );

    Add( 
new TypeNameConverter() );

    Add( 
new EnumConverter() );

    Add( 
new ListConverter() );

    Add( 
new DictionaryConverter() );

    Add( 
new ArrayConverter() ); 

}
这些类型转换器之间的结构图如下:
1
PrimitiveConverter :负责基本数据类型的转换
TypeNameConverter :负责把一个类型的名字转换成这个类型的实例
EnumConverter :负责枚举类型的转换
ListConverter :负责Ilist数据类型的转换
DictionaryConverter :负责Idictionary数据类型转换
ArrayConverter :负责Array数据类型转换
以其中的 PrimitiveConverter 为例来看一下它的实现代码:
public   class  PrimitiveConverter : AbstractTypeConverter
{
    
private Type[] types;

    
public PrimitiveConverter()
    
{
        types 
= new Type[]

            
{
                
typeof (Char),

                
typeof (DateTime),

                
typeof (Decimal),

                
typeof (Boolean),

                
typeof (Int16),

                
typeof (Int32),

                
typeof (Int64),

                
typeof (UInt16),

                
typeof (UInt32),

                
typeof (UInt64),

                
typeof (Byte),

                
typeof (SByte),

                
typeof (Single),

                
typeof (Double),

                
typeof (String)

            }
;
    }


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


    
public override object PerformConversion(String value, Type targetType)
    
{
        
if (targetType == typeof(String)) return value;

        
try
        
{
            
return Convert.ChangeType(value, targetType);

        }

        
catch(Exception ex)
        
{
            String message 
= String.Format(

                
"Could not convert from '{0}' to {1}"

                value, targetType.FullName);

            
throw new ConverterException(message, ex);

        }


    }


    
public override object PerformConversion(IConfiguration configuration, Type targetType)

    
{

        
return PerformConversion(configuration.Value, targetType);

    }


}
可以看到, Castle IOC会把所有的配置参数都当作 String类型接收,如果目标类型是 String,则直接返回结果,否则再进行类型转换。由此我们可以分析得出,要实现自己的类型转换,有以下两步:
1 .编写的自己的类型转换类,实现接口ITypeConverter
// 出处: [url]http://terrylee.cnblogs.com[/url]
public   class  MyTypeConverter : ITypeConverter
{
    
//
}
2 .添加自己的类型转换到 ConversionManager
IKernel kernel  =   new  DefaultKernel();

IConversionManager conversionMng 
=  (IConversionManager) 

    kernel.GetSubSystem( SubSystemConstants.ConversionManagerKey );

conversionMng.Add(
new  MyTypeConverter());
 
关于Castle IOC容器中构建配置信息就到这里了,我总共分为了一,二两部分来讲解。Castle IOC系列的文章后续还有很多,希望大家继续关注!










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

相关文章
|
16天前
|
供应链 安全 Cloud Native
阿里云容器服务助力企业构建云原生软件供应链安全
本文基于2024云栖大会演讲,探讨了软件供应链攻击的快速增长趋势及对企业安全的挑战。文中介绍了如何利用阿里云容器服务ACK、ACR和ASM构建云原生软件供应链安全,涵盖容器镜像的可信生产、管理和分发,以及服务网格ASM实现应用无感的零信任安全,确保企业在软件开发和部署过程中的安全性。
|
7天前
|
XML Java 数据格式
Spring容器Bean之XML配置方式
通过对以上内容的掌握,开发人员可以灵活地使用Spring的XML配置方式来管理应用程序的Bean,提高代码的模块化和可维护性。
36 6
|
25天前
|
存储 Prometheus 监控
Docker容器内进行应用调试与故障排除的方法与技巧,包括使用日志、进入容器检查、利用监控工具及检查配置等,旨在帮助用户有效应对应用部署中的挑战,确保应用稳定运行
本文深入探讨了在Docker容器内进行应用调试与故障排除的方法与技巧,包括使用日志、进入容器检查、利用监控工具及检查配置等,旨在帮助用户有效应对应用部署中的挑战,确保应用稳定运行。
32 5
|
1月前
|
机器学习/深度学习 数据采集 Docker
Docker容器化实战:构建并部署一个简单的Web应用
Docker容器化实战:构建并部署一个简单的Web应用
|
2月前
|
Kubernetes 监控 数据中心
容器化与微服务:构建高效开发环境的双剑合璧
【10月更文挑战第20天】本文探讨了容器化技术(如Docker和Kubernetes)与微服务架构的结合,如何共同构建高效、灵活的开发环境。容器化解决了环境一致性、快速部署和资源隔离的问题,而微服务架构则提升了系统的可维护性和可扩展性。通过容器编排工具、CI/CD流程和服务网格,两者的结合进一步优化了开发和运维效率。文章还分享了实施这两项技术的最佳实践和职业心得。
|
1月前
|
Kubernetes 监控 Java
如何在Kubernetes中配置镜像和容器的定期垃圾回收
如何在Kubernetes中配置镜像和容器的定期垃圾回收
|
2月前
|
Kubernetes Cloud Native 云计算
云原生之旅:构建你的第一个容器化应用
【8月更文挑战第75天】在数字化浪潮中,云原生技术成为推动企业创新和效率提升的关键动力。本篇文章将引导你开启云原生之旅,通过一个简易的步骤指南,帮助你构建并部署第一个容器化应用。我们将一起探索Docker容器的魅力,以及如何利用Kubernetes进行集群管理,实现服务的自动化部署、扩展和管理。无论你是云原生新手还是希望深化理解,这篇文章都将为你提供实践操作的启示和深入思考的契机。
|
2月前
|
监控 Kubernetes 测试技术
掌握Docker网络模式:构建高效容器通信
【10月更文挑战第3天】本文深入探讨了Docker的网络模式,包括它们的工作原理、使用场景以及如何配置和优化容器间的通信。希望能够帮助开发者在项目中有效地应用Docker网络模式,构建高效的容器化应用。
|
3月前
|
供应链 安全 Cloud Native
阿里云容器服务助力企业构建云原生软件供应链安全
针对软件供应链的攻击事件在以每年三位数的速度激增,其中三方或开源软件已经成为攻击者关注的重要目标,其攻击方式和技术也在不断演进。通过供应链的传播,一个底层软件包的漏洞的影响范围可以波及世界。企业亟需更加标准和完善的供应链风险洞察和防护机制。本文将结合最佳实践的形式,面向容器应用完整的生命周期展示如何基于容器服务ACK/ACR/ASM助力企业构建云原生软件供应链安全。
|
2月前
|
运维 Kubernetes 开发者
构建高效后端服务:微服务架构与容器化技术的结合
【10月更文挑战第18天】 在数字化转型的浪潮中,企业对后端服务的要求日益提高,追求更高的效率、更强的可伸缩性和更易于维护的系统。本文将探讨微服务架构与容器化技术如何结合,以构建一个既灵活又高效的后端服务体系。通过分析当前后端服务面临的挑战,介绍微服务和容器化的基本概念,以及它们如何相互配合来优化后端服务的性能和管理。本文旨在为开发者提供一种实现后端服务现代化的方法,从而帮助企业在竞争激烈的市场中脱颖而出。
33 0