主要的c# DI/IoC框架比较起来如何?

冒着进入圣战的风险,这些流行的DI/IoC框架的优点和缺点是什么,其中一个可以轻易地被认为是最好的吗?. .:

  • Ninject
  • 团结
  • 城堡。温莎
  • Autofac
  • StructureMap

还有其他我没有在这里列出的c# DI/IoC框架吗?

在我的用例中,我正在构建一个WPF客户端应用程序,WCF/SQL服务基础设施,易用性(特别是在清晰简洁的语法方面),一致的文档,良好的社区支持和性能都是我选择的重要因素。

更新:

所引用的资源和重复的问题似乎已经过时了,那些了解所有这些框架的人能站出来提供一些真正的见解吗?

我知道大多数关于这个主题的观点可能是有偏见的,但我希望有人花时间研究所有这些框架,至少有一个总体上客观的比较。

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

第二次更新:

如果您有使用多个DI/IoC容器的经验,请对它们的优缺点进行排序和总结,谢谢。这并不是一个发现人们所做的所有晦涩的小容器的练习,我正在寻找流行(和活跃)框架之间的比较。

113568 次浏览

在我写这篇文章的时候,看看Net-ioc-frameworks的谷歌代码的比较,包括linfu和spring.net,它们不在你的列表上。

我使用过spring.net:它有很多特性(aop、库、docu……),并且在dotnet和java世界中有很多使用它的经验。这些特性是模块化的,所以你不必采用所有的特性。这些特性是对常见问题的抽象,如数据库抽象、日志抽象。然而,很难进行和调试iocc配置。

从我目前所读到的:如果我必须选择一个小型或中型项目,我会使用ninject,因为iocc配置已经完成,并且可以在c#中调试。但是我还没有使用过它。对于大型模块化系统,我会使用spring.net,因为它有抽象库。

实际上,IoC框架有很多。似乎每个程序员都试图在他们职业生涯的某个阶段写一个。也许不是为了发表,而是为了了解内部工作原理。

我个人更喜欢autofac,因为它非常灵活,有适合我的语法(尽管我真的讨厌所有的注册方法都是扩展方法)。

其他一些框架:

好吧,环顾四周之后,我发现目前为止最好的比较是:

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

我感兴趣的一点是,那些使用过DI/IoC框架并喜欢或不喜欢它的人,StructureMap似乎名列前茅。

同样从民意调查来看,城堡。温莎StructureMap似乎是最受欢迎的。

有趣的是,团结春天。网似乎是最不受欢迎的选项。(我考虑Unity是出于懒惰(以及微软的徽章/支持),但我现在会更仔细地研究温莎城堡和StructureMap。)

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

希望其他人可以根据直接经验进行比较。

虽然对这个问题的全面回答需要花费数百页的我的书,但这里有一个我仍在研究的快速比较图表:

A table解释between几个DICs

读一下Philip Mat的.Net DI容器比较博客就知道了。

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

他推荐Autofac,因为它很小,快速,易于使用…我同意。看来团结Ninject在他的测试中是最慢的。

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

以下是这篇文章的简要总结:

结论

Ninject绝对是最慢的容器。

MEF,林甫和春天。NET比Ninject快,但仍然很漂亮 缓慢。接下来是AutoFac, Catel和Windsor,然后是StructureMap, Unity和LightCore。Spring的一个缺点。NET是,那只能是

. XML SimpleInjector, Hiro, Funq, Munq和Dynamo提供最好的 性能方面,它们非常快。试一试吧!< / p > 特别是简单注入器似乎是一个不错的选择。它非常快,有一个很好的 文档,还支持高级场景,如拦截

你也可以尝试使用公共服务选择器库,并希望尝试多个选项,看看哪个最适合你。

关于公共服务选择器库的一些信息:

这个库提供了IoC容器和服务的抽象 定位器。使用库允许应用程序间接访问 不依赖于硬引用的功能。希望是 使用这个库,第三方应用程序和框架可以启动 来利用IoC/服务位置,而不将自己束缚在 具体实现。< / p >

更新

13.09.2011: FunqMunq被添加到参赛者名单中。图表也更新了,Spring。NET由于性能不佳而被删除。

04.11.2011: "补充简单的注射器,表现是最好的所有参赛者"

截至2015年初,IoC容器特性吉米伯加德之间有很大的比较,以下是摘要:

容器相比:

  • 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;
}

然后我创建了一个请求/响应/通知的基本集:

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 { }

我对一些关于泛型容器支持的事情很感兴趣:

  • 开放泛型的设置(很容易注册IRequestHandler< >)
  • 设置开放泛型的多个注册(两个或多个) 李INotificationHandlers) < / >

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

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();
  • 开放泛型:是的,隐式地
  • 多重开放泛型:是的,隐式地
  • 泛型逆变:是的,显式的

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);
  • 开放泛型:是的,隐式地
  • 多重开放泛型:是的,隐式地
  • 一般的矛盾性:是的,使用用户构建的扩展

简单的注射器

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);
  • 开放泛型:是的,显式地
  • 多重开放泛型:是的,显式地
  • 泛型逆变:是,隐式的(更新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<>));
});
});
  • 开放泛型:是的,显式地
  • 多重开放泛型:是的,显式地
  • 泛型逆变:是的,隐式的

团结

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;
}
  • 开放泛型:是的,隐式地
  • 多个开放泛型:是的,带有用户构建的扩展
  • 泛型逆变:derp

温莎

var container = new WindsorContainer();
container.Register(Classes.FromAssemblyContaining<IMediator>().Pick().WithServiceAllInterfaces());
container.Register(Classes.FromAssemblyContaining<Ping>().Pick().WithServiceAllInterfaces());
container.Kernel.AddHandlersFilter(new ContravariantFilter());
  • 开放泛型:是的,隐式地
  • 多重开放泛型:是的,隐式地
  • 一般的矛盾性:是的,使用用户构建的扩展