码迷,mamicode.com
首页 > 编程语言 > 详细

spring.net 泛型接口注入+泛型接口结合协变注入

时间:2015-01-30 21:02:48      阅读:161      评论:0      收藏:0      [点我收藏+]

标签:

首先看下 spring.net 操作手册中关于类型别名的说明

  

4.12.3.注册类型别名

作为类型全名的替代物,类型别名可以简化Spring.NET的配置文件。别名可以在config文件中注册,也可以通过编程方式注册,注册之后就可以在对象定义中任何需要类型全名的地方使用。也可以为泛型类定义类型别名。

若要配置类型别名,一种方式是在Web/App.config文件中添加typeAliases节点和相应的节点处理器。请参看本节一开始的例子,其中为WebServiceExporter类定义了一个类型别名。一旦定义了类型别名,就可以象全名一样使用它们:

<object id="MyWebService" type="WebServiceExporter">
    ...
</object>

<object id="cacheAspect" type="DefaultPointcutAdvisor">
    <property name="Pointcut">
        <object type="AttributePointcut">
            <property name="Attribute" value="CacheAttribute"/>       
        </object>

    </property>
    <property name="Advice" ref="aspNetCacheAdvice"/>
</object>

关于如何为泛型类型定义类型别名,请参看4.2.4,创建泛型类型的对象

另外,也可以通过Spring.Objects.Factory.Config.TypeAliasConfigurer类来注册类型别名。这种定义方法更加模块化,如果没有App/Web.config,也可以通过这种方式注册别名。请看下面的例子:

<object id="myTypeAlias" type="Spring.Objects.Factory.Config.TypeAliasConfigurer, Spring.Core">
      <property name="TypeAliases">
          <dictionary>
              <entry key="WebServiceExporter" value="Spring.Web.Services.WebServiceExporter, Spring.Web"/>

              <entry key="DefaultPointcutAdvisor" value="Spring.Aop.Support.DefaultPointcutAdvisor, Spring.Aop"/>
              <entry key="MyType" value="MyCompany.MyProject.MyNamespace.MyType, MyAssembly"/>
          </dictionary>
      </property>
</object>

再看泛型接口注入说明

4.2.4.泛型类的对象创建

泛型对象的创建方法和普通对象是一样的。

4.2.4.1.通过构造器创建泛型对象

下面是一个泛型类的代码:

namespace GenericsPlay
{
    public class FilterableList<T>
    {
        private List<T> list;
        
        private String name;

        public List<T> Contents
        {
            get { return list; }
            set { list = value; }
        }

        public String Name
        {
            get { return name; }
            set { name = value; }
        }
        
        public List<T> ApplyFilter(string filterExpression)
        {
            /// should really apply filter to list ;)
            return new List<T>();
        }

    }
}

下面是该类的对象定义:

<object id="myFilteredIntList" type="GenericsPlay.FilterableList&lt;int>, GenericsPlay">
  <property name="Name" value="My Integer List"/>
</object>

在为泛型类对象指定type属性的时候要注意:第一,左尖括号<要替换成字符串“&lt;”,因为在XML中左尖括号会被认为是小于号。从可读性来讲,我们都知道这并不是理想的方式。第二,type参数值中不能包含程序集的名称,因为程序集名称要求和类型全名用逗号隔开,而在这里逗号已经被用来分隔泛型类的类型参数了。将来可能会用其它字符代替这两个符号,但目前还没找到更具可读性的方案。若要提高可读性,建议使用类型别名,如下所示:

<typeAliases>
 <alias name="GenericDictionary" type=" System.Collections.Generic.Dictionary&lt;,>" />
 <alias name="myDictionary" type="System.Collections.Generic.Dictionary&lt;int,string>" />
</typeAliases>

然后,下面的对象定义:

<object id="myGenericObject" 
        type="GenericsPlay.ExampleGenericObject&lt;System.Collections.Generic.Dictionary&lt;int , string>>, GenericsPlay" />

就可以缩短为:

<object id="myOtherGenericObject" 
        type="GenericsPlay.ExampleGenericObject&lt;GenericDictionary&lt;int , string>>, GenericsPlay" />

或者更短:

<object id="myOtherOtherGenericObject" 
        type="GenericsPlay.ExampleGenericObject&lt;MyIntStringDictionary>, GenericsPlay" />


下面来看例子
    /// <summary>
    /// 模型接口
    /// </summary>
    public interface IModel { }
    /// <summary>
    /// 模型实现
    /// </summary>
    public class Model : IModel { }
    /// <summary>
    /// 泛型接口 
/// </summary> /// <typeparam name="T"></typeparam> public interface GenericsInterface<out T> where T : IModel { } /// <summary> /// 泛型接口实现类 /// </summary> /// <typeparam name="T"></typeparam> public class GenericsClass<T> : GenericsInterface<T> where T : IModel { }
   public class GenericsClassTest
    {
        public Dictionary<int, GenericsInterface<Model>> dic { get; set; }
        public Dictionary<int, GenericsClass<Model>> dic1 { get; set; }
        public Dictionary<int, GenericsInterface<IModel>> dic2 { get; set; }
        public List<GenericsInterface<Model>> list { get; set; }
        public List<GenericsClass<Model>> list1 { get; set; }
        public GenericsInterface<Model> gi { get; set; }
        /// <summary>
        /// 成功-因为这里是 协变的接口
        /// </summary>
        public GenericsInterface<IModel> gi1 { get; set; }
    }

 看配置文件

<!--配置-->
		<objects xmlns="http://www.springframework.net">
			<!--类型别名注入-->
			<object id="myTypeAlias" type="Spring.Objects.Factory.Config.TypeAliasConfigurer, Spring.Core">
				<property name="TypeAliases">
					<dictionary>
						<entry key="type1" value="spring.net.Model,spring.net"></entry>
						<entry key="type2" value="spring.net.IModel,spring.net"></entry>
					</dictionary>
				</property>
			</object>

			<object name="gc1" type="spring.net.GenericsClass<type1>,spring.net"></object>
			<object name="p1" type="spring.net.GenericsClassTest,spring.net">
				<property name="gi" ref="gc1"></property>
				<property name="gi1" ref="gc1"></property>
				<property name="dic">
					<dictionary key-type="int" value-type="spring.net.GenericsInterface<type1>,spring.net">
						<entry key="1" value-ref="gc1"></entry>
					</dictionary>
				</property>
				<property name="dic1">
					<dictionary key-type="int" value-type="spring.net.GenericsClass<type1>,spring.net">
						<entry key="1" value-ref="gc1"></entry>
					</dictionary>
				</property>
				<property name="dic2">
					<dictionary key-type="int" value-type="spring.net.GenericsInterface<type2>,spring.net">
						<entry key="1" value-ref="gc1"></entry>
					</dictionary>
				</property>
				<property name="list">
					<list element-type="spring.net.GenericsInterface<type1>,spring.net">
						<ref object="gc1"/>
						<ref object="gc1"/>
					</list>
				</property>
				<property name="list1">
					<list element-type="spring.net.GenericsClass<type1>,spring.net">
						<ref object="gc1"/>
						<ref object="gc1"/>
					</list>
				</property>
			</object>

 

其它的不做说明

类中的属性 dic2 与 gi1 在使用 泛型接口的同时,参数同时也为接口

所以我们声明的时候 指定泛型接口的参数为 协变参数

这样就可以处理

spring.net 泛型接口注入+泛型接口结合协变注入

标签:

原文地址:http://www.cnblogs.com/yinhz/p/4263106.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!