主要的C#DI / IoC框架如何比较?

冒着步入圣战疆域的风险,这些stream行的DI / IoC框架的优点和缺点是什么,可以轻易认为是最好的? ..:

  • Ninject
  • 统一
  • Castle.Windsor
  • Autofac
  • StructureMap

有没有其他的DI / IoC框架的C#,我没有在这里列出?

在我的用例的上下文中,我构build了一个客户端WPF应用程序和一个WCF / SQL服务基础架构,易用性(特别是语法清晰简洁),一致的文档,良好的社区支持和性能都是重要的因素在我的select。

更新:

所引用的资源和重复问题似乎已经过时,能否有一个知道所有这些框架的人出面并提供一些真正的洞察力?

我意识到这个问题上的大多数意见可能是有偏见的,但我希望有人花时间研究所有这些框架,并至less有一个客观的比较。

如果以前没有做过,我很乐意做自己的调查,但是我认为这是至less有一些人已经做了。

第二次更新:

如果您对多个DI / IoC容器有经验,请对这些容器的优缺点进行sorting和总结,谢谢。 这不是发现人们所有的模糊小容器的练习,我正在寻找stream行的(和主动的)框架之间的比较。

7 Solutions collect form web for “主要的C#DI / IoC框架如何比较?”

虽然这个问题的综合答案占了我的书的数百页,这是一个快速的比较图表,我还在努力:

替代文字

我遇到了另一个性能比较 (最新更新2014年4月10日)。 它比较如下:

  • AutoFac
  • LightCore (网站是德语)
  • 李林甫
  • Ninject
  • 娇小
  • 简单的喷油器 (所有参赛者中最快的)
  • Spring.NET
  • StructureMap
  • 统一
  • 温莎

以下是post的简要总结:

结论

Ninject绝对是最慢的容器。

MEF,LinFu和Spring.NET比Ninject快,但是还是很慢。 接下来是AutoFac,Catel和Windsor,其次是StructureMap,Unity和LightCore。 Spring.NET的缺点是,只能用XMLconfiguration。

SimpleInjector,Hiro,Funq,Munq和Dynamo提供了最好的性能,它们非常快。 给他们一个尝试!

尤其是简单的喷油器似乎是一个不错的select。 它非常快,有一个很好的文档,并支持先进的scheme,如拦截和通用装饰器。

您也可以尝试使用通用服务select器库,并希望尝试多个选项,并查看哪些最适合您。

关于通用服务select器库的一些通知:

该库提供了对IoC容器和服务定位器的抽象。 使用库允许应用程序间接访问function而不依赖于硬引用。 希望通过使用这个库,第三方应用程序和框架可以开始利用IoC /服务位置,而不必将自己绑定到特定的实现。

更新

2011年9月 13日 Funq和Munq被列入参赛名单。 图表也被更新了,由于性能不佳,Spring.NET被删除了。

2011年11月4日: “添加简单的喷油器 ,performance是所有参赛者中最好的”。

只要阅读Philip Mat这个伟大的.Net DI容器比较博客 。

他做了一些彻底的性能比较testing;

  • Autofac
  • StructureMap
  • Ninject
  • 统一
  • Castle.Windsor
  • Spring.Net

他build议Autofac,因为它小巧,快速,易于使用…我同意。 Unity和Ninject似乎是他testing中速度最慢的。

免责声明:截至2015年初, Jimmy Bogard的IoC容器function有很大的比较,下面是一个总结:

比较容器:

  • Autofac
  • Ninject
  • 简单的喷油器
  • StructureMap
  • 统一
  • 温莎

情况是这样的:我有一个接口,IMediator,我可以发送一个请求/响应或通知给多个收件人:

public interface IMediator { TResponse Send<TResponse>(IRequest<TResponse> request); Task<TResponse> SendAsync<TResponse>(IAsyncRequest<TResponse> request); void Publish<TNotification>(TNotification notification) where TNotification : INotification; Task PublishAsync<TNotification>(TNotification notification) where TNotification : IAsyncNotification; } 

然后我创build了一组请求/响应/通知:

 public class Ping : IRequest<Pong> { public string Message { get; set; } } public class Pong { public string Message { get; set; } } public class PingAsync : IAsyncRequest<Pong> { public string Message { get; set; } } public class Pinged : INotification { } public class PingedAsync : IAsyncNotification { } 

我感兴趣的是关于generics的容器支持的几件事情:

  • 设置打开的generics(轻松注册IRequestHandler <,>)
  • 设置多个注册的开放式generics(两个或更多的INotificationHandlers)

通用差异的设置(注册基础INotification的处理程序/创build请求pipe道)我的处理程序非常简单,只是输出到控制台:

 public class PingHandler : IRequestHandler<Ping, Pong> { /* Impl */ } public class PingAsyncHandler : IAsyncRequestHandler<PingAsync, Pong> { /* Impl */ } public class PingedHandler : INotificationHandler<Pinged> { /* Impl */ } public class PingedAlsoHandler : INotificationHandler<Pinged> { /* Impl */ } public class GenericHandler : INotificationHandler<INotification> { /* Impl */ } public class PingedAsyncHandler : IAsyncNotificationHandler<PingedAsync> { /* Impl */ } public class PingedAlsoAsyncHandler : IAsyncNotificationHandler<PingedAsync> { /* Impl */ } 

Autofac

 var builder = new ContainerBuilder(); builder.RegisterSource(new ContravariantRegistrationSource()); builder.RegisterAssemblyTypes(typeof (IMediator).Assembly).AsImplementedInterfaces(); builder.RegisterAssemblyTypes(typeof (Ping).Assembly).AsImplementedInterfaces(); 
  • 开放generics:是的,隐式的
  • 多个开放的generics:是的,隐式的
  • 一般的反变化:是的,明确的

Ninject

 var kernel = new StandardKernel(); kernel.Components.Add<IBindingResolver, ContravariantBindingResolver>(); kernel.Bind(scan => scan.FromAssemblyContaining<IMediator>() .SelectAllClasses() .BindDefaultInterface()); kernel.Bind(scan => scan.FromAssemblyContaining<Ping>() .SelectAllClasses() .BindAllInterfaces()); kernel.Bind<TextWriter>().ToConstant(Console.Out); 
  • 开放generics:是的,隐式的
  • 多个开放的generics:是的,隐式的
  • 通用反转:是的,用户构build的扩展

简单的喷油器

 var container = new Container(); var assemblies = GetAssemblies().ToArray(); container.Register<IMediator, Mediator>(); container.Register(typeof(IRequestHandler<,>), assemblies); container.Register(typeof(IAsyncRequestHandler<,>), assemblies); container.RegisterCollection(typeof(INotificationHandler<>), assemblies); container.RegisterCollection(typeof(IAsyncNotificationHandler<>), assemblies); 
  • 开放generics:是的,明确的
  • 多种开放的generics:是的,明确的
  • 一般的反变化:是的,含蓄地(与更新3.0)

StructureMap

 var container = new Container(cfg => { cfg.Scan(scanner => { scanner.AssemblyContainingType<Ping>(); scanner.AssemblyContainingType<IMediator>(); scanner.WithDefaultConventions(); scanner.AddAllTypesOf(typeof(IRequestHandler<,>)); scanner.AddAllTypesOf(typeof(IAsyncRequestHandler<,>)); scanner.AddAllTypesOf(typeof(INotificationHandler<>)); scanner.AddAllTypesOf(typeof(IAsyncNotificationHandler<>)); }); }); 
  • 开放generics:是的,明确的
  • 多种开放的generics:是的,明确的
  • 一般的反变化:是的,含蓄地

统一

 container.RegisterTypes(AllClasses.FromAssemblies(typeof(Ping).Assembly), WithMappings.FromAllInterfaces, GetName, GetLifetimeManager); /* later down */ static bool IsNotificationHandler(Type type) { return type.GetInterfaces().Any(x => x.IsGenericType && (x.GetGenericTypeDefinition() == typeof(INotificationHandler<>) || x.GetGenericTypeDefinition() == typeof(IAsyncNotificationHandler<>))); } static LifetimeManager GetLifetimeManager(Type type) { return IsNotificationHandler(type) ? new ContainerControlledLifetimeManager() : null; } static string GetName(Type type) { return IsNotificationHandler(type) ? string.Format("HandlerFor" + type.Name) : string.Empty; } 
  • 开放generics:是的,隐式的
  • 多个开放的generics:是的,用户build立的扩展
  • 通用反转:derp

温莎

 var container = new WindsorContainer(); container.Register(Classes.FromAssemblyContaining<IMediator>().Pick().WithServiceAllInterfaces()); container.Register(Classes.FromAssemblyContaining<Ping>().Pick().WithServiceAllInterfaces()); container.Kernel.AddHandlersFilter(new ContravariantFilter()); 
  • 开放generics:是的,隐式的
  • 多个开放的generics:是的,隐式的
  • 通用反转:是的,用户build立的扩展

实际上有大量的IoC框架。 看起来每个程序员都试图在他们职业生涯的某个时候写一个。 也许不发表它,而是要学习内在的运作。

我个人更喜欢autofac,因为它非常灵活,并有适合我的语法(虽然我真的恨所有注册方法是扩展方法)。

其他一些框架:

那么,环顾目前我发现的最好的比较是:

这是在2010年3月进行的一项民意调查。

我感兴趣的一点是,使用DI / IoC框架并喜欢/不喜欢它的人,StructureMap似乎排在前列。

同样从民意调查来看, Castle.Windsor和StructureMap似乎是最受青睐的。

有趣的是, Unity和Spring.Net似乎是最普遍不喜欢的stream行选项。 (我从懒惰(和微软徽章/支持)考虑Unity,但我现在将更加关注Castle Windsor和StructureMap。)

当然这可能(?)不适用于2010年5月发布的Unity 2.0。

希望别人能够根据直接经验提供一个比较。

在我写这段文字的时候,请查看一下包括linfu和spring.net在内的google代码的net-ioc-frameworks的比较。

我和spring.net一起工作过:它有许多function(aop,libraries,docu,…),在dotnet和java世界里有很多的经验。 function模块化,所以你不必采取所有function。 这些function是像数据库抽象,日志摘要这样的常见问题的抽象概念。 然而,执行和debuggingIoCconfiguration是很困难的。

从目前为止我读到的:如果我不得不select一个小型或中型项目,我会使用ninject,因为iocconfiguration完成并可以在c#中debugging。 但我还没有与它合作。 对于大的模块化系统,我会留在spring.net,因为抽象库。

  • WebActivator做什么?
  • 什么是Ninject,什么时候使用它?
  • 我应该在哪里做Ninject 2+注射(以及如何安排我的模块?)
  • N注入通用接口
  • Ninject:使用Ninject注册一个已经创build的实例?
  • ObjectStateManager中已经存在具有相同键的对象。 ObjectStateManager不能使用同一个键跟踪多个对象
  • Ninject示例应用程序?
  • Ninject InRequestScope丢失
  • Ninject是否支持Func(自动生成的工厂)?
  • NInject:你在哪里保持你对内核的引用?
  • validation:如何使用Ninject注入模型状态包装器?