[转]多个IoC容器适配器设计及性能测试和容器选择

1. 采用的IoC容器和版本

Autofac.2.6.3.862

Castle.Windsor.3.1.0

Spring.Core.2.0.0

2. 基础类库:服务类库和组件类库及相关的辅助类库

辅助类库:Demo.Common.dll

服务接口类库:Demo.Lib.dll

Oracle组件类库:Demo.Lib.Oracle.dll

Sql组件类库:Demo.Lib.Sql.dll

3. Autofac容器适配器

using Autofac;

using System;

namespace IoC.Core.Adapter
{
public sealed class AutofacContainerAdapter : IContainerAdapter
{
public AutofacContainerAdapter()
{
Prepare();
}
private IContainer container; public void Prepare()
{
var autofacContainerBuilder = new ContainerBuilder(); //autofacContainerBuilder.RegisterType<Singleton>()
// .As<ISingleton>()
// .SingleInstance(); //autofacContainerBuilder.RegisterType<Transient>()
// .As<ITransient>(); //autofacContainerBuilder.RegisterType<Combined>()
// .As<ICombined>(); this.container = autofacContainerBuilder.Build();
} public T Resolve<T>()
{
return this.container.Resolve<T>();
} public T Resolve<T>(string ServiceName)
{
return this.container.ResolveNamed<T>(ServiceName);
} public void Dispose()
{
// Allow the container and everything it references to be disposed.
this.container = null;
} public void Register(Type TService, Type TImplementation, string ServiceName, LifeCycleType LifeCycle = LifeCycleType.Transient)
{
if (!string.IsNullOrEmpty(ServiceName) && !container.IsRegisteredWithName(ServiceName, TService))
{
var autofacContainerBuilder = new ContainerBuilder(); var item = autofacContainerBuilder.RegisterType(TImplementation); if (!string.IsNullOrEmpty(ServiceName))
{
item = item.Named(ServiceName, TService);
}
else
{
item = item.As(TService);
} switch (LifeCycle)
{
case LifeCycleType.Singleton:
item = item.SingleInstance();
break;
case LifeCycleType.Transient:
item = item.InstancePerDependency();
break;
case LifeCycleType.Request:
item = item.InstancePerLifetimeScope();
break;
} //if (!string.IsNullOrEmpty(ServiceName))
//{
// autofacContainerBuilder.RegisterType(TImplementation).Named(ServiceName, TService);
//}
//else
//{
// autofacContainerBuilder.RegisterType(TImplementation).As(TService);
//} //container = autofacContainerBuilder.Build();
autofacContainerBuilder.Update(container);
}
} public void Register(string TServiceFull, string TImplementationFull, string ServiceName, LifeCycleType LifeCycle = LifeCycleType.Transient)
{
Type TService = Type.GetType(TServiceFull);
Type TImplementation = Type.GetType(TImplementationFull); if (!string.IsNullOrEmpty(ServiceName) && !container.IsRegisteredWithName(ServiceName, TService))
{
Register(TService, TImplementation, ServiceName, LifeCycle);
} } public void Register(Type TService, Type TImplementation, LifeCycleType LifeCycle)
{
string ServiceName = TImplementation.GetType().Name;
Register(TService, TImplementation, ServiceName, LifeCycle);
} public void Register(string TServiceFull, string TImplementationFull, LifeCycleType LifeCycle)
{
if (!string.IsNullOrEmpty(TImplementationFull))
{
string ServiceName = TImplementationFull;
if (TImplementationFull.IndexOf(",") > 0)
{
ServiceName = TImplementationFull.Substring(0, TImplementationFull.IndexOf(","));
}
Register(TServiceFull, TImplementationFull, ServiceName, LifeCycle);
}
} }
}

4. Castle.Windsor容器适配器

using Castle.MicroKernel.Registration;
using Castle.Windsor; using System;
using System.Collections.Generic; namespace IoC.Core.Adapter
{
public sealed class WindsorContainerAdapter : IContainerAdapter
{
public WindsorContainerAdapter()
{
Prepare();
}
private WindsorContainer container; public void Prepare()
{
this.container = new WindsorContainer(); //this.container.Register(Component.For<ISingleton>().ImplementedBy<Singleton>());
//this.container.Register(Component.For<ITransient>().ImplementedBy<Transient>().LifeStyle.Transient);
//this.container.Register(Component.For<ICombined>().ImplementedBy<Combined>().LifeStyle.Transient);
} public T Resolve<T>()
{
return this.container.Resolve<T>();
} public T Resolve<T>(string ServiceName)
{ return this.container.Resolve<T>(ServiceName);
} public void Dispose()
{
// Allow the container and everything it references to be disposed.
this.container = null;
} private IDictionary<string, string> NameDict = new Dictionary<string, string>(); public void Register(Type TService, Type TImplementation, string ServiceName, LifeCycleType LifeCycle = LifeCycleType.Transient)
{
if (!string.IsNullOrEmpty(ServiceName) && !NameDict.ContainsKey(ServiceName))
{
var item = Component.For(TService).ImplementedBy(TImplementation); switch (LifeCycle)
{
case LifeCycleType.Singleton:
item = item.LifestyleSingleton();
break;
case LifeCycleType.Transient:
item = item.LifestyleTransient();
break;
case LifeCycleType.Request:
item = item.LifestylePerWebRequest();
break;
} if (!string.IsNullOrEmpty(ServiceName))
{
item = item.Named(ServiceName);
NameDict[ServiceName] = null;
} container.Register(item); } } public void Register(string TServiceFull, string TImplementationFull, string ServiceName, LifeCycleType LifeCycle = LifeCycleType.Transient)
{
if (!string.IsNullOrEmpty(ServiceName) && !NameDict.ContainsKey(ServiceName))
{ Type TService = Type.GetType(TServiceFull);
Type TImplementation = Type.GetType(TImplementationFull); Register(TService, TImplementation, ServiceName, LifeCycle); } } public void Register(Type TService, Type TImplementation, LifeCycleType LifeCycle)
{
string ServiceName = TImplementation.GetType().Name;
Register(TService, TImplementation, ServiceName, LifeCycle);
} public void Register(string TServiceFull, string TImplementationFull, LifeCycleType LifeCycle)
{
if (!string.IsNullOrEmpty(TImplementationFull))
{
string ServiceName = TImplementationFull;
if (TImplementationFull.IndexOf(",") > 0)
{
ServiceName = TImplementationFull.Substring(0, TImplementationFull.IndexOf(","));
}
Register(TServiceFull, TImplementationFull, ServiceName, LifeCycle);
}
} }
}

5. Spring.NET的容器适配器

using Spring.Core;
using Spring.Context;
using Spring.Context.Support;
using Spring.Objects.Factory.Support; using System; namespace IoC.Core.Adapter
{
public sealed class SpringContainerAdapter : IContainerAdapter
{
public SpringContainerAdapter()
{
Prepare();
} private GenericApplicationContext container; public void Prepare()
{
//this.container = Spring.Context.Support.ContextRegistry.GetContext();
container = new GenericApplicationContext();
} public T Resolve<T>()
{
return (T)container.GetObject(typeof(T).FullName);
} public T Resolve<T>(string ServiceName)
{
return (T)container.GetObject<T>(ServiceName);
} public void Dispose()
{
// Allow the container and everything it references to be disposed.
this.container = null;
} public void Register(Type TService, Type TImplementation, string ServiceName, LifeCycleType LifeCycle = LifeCycleType.Transient)
{ if (!string.IsNullOrEmpty(ServiceName) && !container.IsObjectNameInUse(ServiceName))
{
string vName = TImplementation.GetType().ToString();
string TImplementationFull = vName + ", " + TImplementation.Assembly.ToString();
IObjectDefinitionFactory factory = new DefaultObjectDefinitionFactory();
AbstractObjectDefinition defi = factory.CreateObjectDefinition(TImplementationFull, null, AppDomain.CurrentDomain); string SpringObjeLifeCycle = "singleton";//"prototype" "request";
switch (LifeCycle)
{
case LifeCycleType.Singleton:
SpringObjeLifeCycle = "singleton";
break;
case LifeCycleType.Transient:
SpringObjeLifeCycle = "prototype";
break;
case LifeCycleType.Request:
SpringObjeLifeCycle = "request";
break;
}
defi.Scope = SpringObjeLifeCycle; //建立容器
//GenericApplicationContext tmpContainer = container as GenericApplicationContext;
container.RegisterObjectDefinition(ServiceName, defi); } } public void Register(string TServiceFull, string TImplementationFull, string ServiceName, LifeCycleType LifeCycle = LifeCycleType.Transient)
{
if (!string.IsNullOrEmpty(ServiceName) && !container.IsObjectNameInUse(ServiceName))
{ IObjectDefinitionFactory factory = new DefaultObjectDefinitionFactory();
AbstractObjectDefinition defi = factory.CreateObjectDefinition(TImplementationFull, null, AppDomain.CurrentDomain); string SpringObjeLifeCycle = "singleton";//"prototype" "request";
switch (LifeCycle)
{
case LifeCycleType.Singleton:
SpringObjeLifeCycle = "singleton";
break;
case LifeCycleType.Transient:
SpringObjeLifeCycle = "prototype";
break;
case LifeCycleType.Request:
SpringObjeLifeCycle = "request";
break;
}
defi.Scope = SpringObjeLifeCycle; string vFullName = Type.GetType(TImplementationFull).FullName;
//建立容器
//GenericApplicationContext tmpContainer = container as GenericApplicationContext;
container.RegisterObjectDefinition(vFullName, defi);
} } public void Register(Type TService, Type TImplementation, LifeCycleType LifeCycle)
{
string ServiceName = TImplementation.GetType().Name;
Register(TService, TImplementation, ServiceName, LifeCycle);
} public void Register(string TServiceFull, string TImplementationFull, LifeCycleType LifeCycle)
{
if (!string.IsNullOrEmpty(TImplementationFull))
{
string ServiceName = TImplementationFull;
if (TImplementationFull.IndexOf(",") > 0)
{
ServiceName = TImplementationFull.Substring(0, TImplementationFull.IndexOf(","));
}
Register(TServiceFull, TImplementationFull, ServiceName, LifeCycle);
}
}
}
}

6. 测试结果

6.1. 单例模式

6.2. 瞬时(多例)模式

7. 测试结论

(1) 不管是单例还是多例,初始化的时间都差不多,Autofac略快

Autofac略快
 Spring和Windsor略慢,但两者相差不大

(2) 不管是单例还是多例,非初始化取数据时,取数据量大时,花费的时间也大

(3) 单例时,性能比较,Autofac略慢,但差异不大

Spring和Windsor花费时间差不多
 Autofac比较慢

(4) 多例时,性能比较,Autofac速度最快,也最稳定,差异较大

Autofac速度最快,相当稳定
 Windsor速度居中:是Autofac的1~2倍
 Spring速度最慢: 是Autofac的5~6倍左右

8. IoC容器选择结论(Autofac第一名)

A. 单例时,Autofac会略慢,但相差不大

B. 多例时,Autofac速度明显较快,Spring性能下降太厉害

C. 整体而言,Autofac的优劣较明显

D. 性能对比,Autofac > Windsor > Spring

9. Demo下载

点此下载

多个IoC容器适配器设计及性能测试(Castle.Windsor Autofac Spring.Core)的更多相关文章

  1. Spring源码解析-ioc容器的设计

    Spring源码解析-ioc容器的设计 1 IoC容器系列的设计:BeanFactory和ApplicatioContext 在Spring容器中,主要分为两个主要的容器系列,一个是实现BeanFac ...

  2. Spring源码阅读:IOC容器的设计与实现(二)——ApplicationContext

    上一主题(查看)中,了解了IOC容器的基本概念,以及BeanFactory的设计与实现方式,这里就来了解一下ApplicationContext方式的实现. ApplicationContext 在S ...

  3. Spring IoC容器的设计——BeanFactory应用场景2

    1.BeanFactory接口设计了getBean方法,这个方法是使用IoC容器API的主要方法,通过这个方法,可以取得IoC容器中管理的Bean,Bean的取得是通过指定名字来索引的. 2.如果需要 ...

  4. Spring IoC容器的设计——BeanFactory应用场景

    1.BeanFactory提供的是最基本的IoC容器的功能,关于这些功能定义,我们可以在接口BeanFatory中看到. 2.BeanFactory接口定义了IoC容器最基本的容器的形式,并且提供了I ...

  5. Spring IoC容器的设计—3—次线

    这里涉及的是主要接口关系,而具体的IoC容器都是在这个接口体系下实现的,比如DefaultListableBeanFactory,这个基本IoC容器的实现就是实现了ConfigurableBeanFa ...

  6. Spring IoC容器的设计—2—主线

    第二条接口设计主线是,以ApplicationContext应用上下文接口为核心的接口设计,这里涉及的主要接口设计有,从BeanFactory到ListableBeanFactory,再到Applic ...

  7. Spring IoC容器的设计—1—主线

    IoC容器的接口设计图 下面对接口关系做一些简要的分析,可以依据以下内容来理解这张接口设计图. 从接口BeanFactory到HierarchicalBeanFactory,再到Configurabl ...

  8. Spring IoC容器与应用上下文的设计与实现

    一.前言 写这篇博文的主要目的如下: 通过相关类和接口分析IoC容器到底长什么样. 阐述笔者对Spring上下文和容器的理解. 介绍重要的类辅助理解SpringBoot的启动流程. 二.Spring ...

  9. BeanFactory容器的设计原理

    XmlBeanFactory设计的类继承关系 1.BeanFactory接口提供了使用IoC容器的规范.在这个基础上,Spring还提供了符合这个IoC容器接口的一系列容器的实现供开发人员使用. 2. ...

随机推荐

  1. go exec:exit status 64

    接上一篇,找到了查看未读邮件个数方法,需要用go来执行doveadm命令,于是考虑使用go exec包 但是代码写好了之后一直报错:exit status 64,意思是选项错误,但是明明所有选项都是o ...

  2. android下使用adb启动程序或者服务

    susetprop service.adb.tcp.prot 5555stop adbdstart adbdnetstat 使用 adb install hello.apk可以安装一个apk但并不能启 ...

  3. tf.constant

    tf.constant constant( value, dtype=None, shape=None, name='Const', verify_shape=False ) 功能说明: 根据 val ...

  4. TRUNC 截取日期或数字,返回指定的值。

    TRUNC(number,num_digits) Number 需要截尾取整的数字. Num_digits 用于指定取整精度的数字.Num_digits 的默认值为 0.   /*********** ...

  5. pymongo 使用测试

    >>> import pymongo >>> uri = "mongodb://recall:123456@oceanic.mongohq.com:100 ...

  6. FileNet P8 工作流生命周期管理和 Process Engine API 应用介绍

    摘录:https://www.ibm.com/developerworks/cn/data/library/techarticles/dm-0902wangzheng/ FileNet P8 工作流生 ...

  7. 联通GWH-01路由猫超级用户登录方法

    . . . . . 今天回老家,家里用的是联通GWH-01路由猫,上海贝尔的.用路由器背面说明上面写的user用户登录之后,发现只能查看却无法设置.为了开启无线路由功能,只好在网上查找超级用户,是cu ...

  8. JQUERY双下拉框内容的左右移动

     教程源码:http://bbs.php100.com/read-htm-tid-74060.html用到的方法为:appendTo() 格式:$(content).appendTo(selector ...

  9. Xcode搭建Python编译环境

    * {-webkit-tap-highlight-color: rgba(0,0,0,0);}html {-webkit-text-size-adjust: none;}body {font-fami ...

  10. InstallShield Build错误:Internal build error 6041

    点击左侧菜单: Media-Release-选择release版本(例如Release1)-Build标签-   keey unused directories 改为no(默认为yes)