冒着进入神圣战争领域的风险,这些流行的DI / IoC框架有哪些优点和缺点,可以轻松地被认为是最好的? ..:
C#还有其他我没有在此列出的DI / IoC框架吗?
在我的用例的上下文中,我正在构建一个客户端WPF应用程序,一个WCF / SQL服务基础架构,易用性(特别是在清晰简洁的语法方面),一致的文档,良好的社区支持和性能我选择的所有重要因素。
所引用的资源和重复问题似乎已经过时,那些了解所有这些框架的人能否提出并提供一些真正的见解?
我意识到关于这个主题的大多数意见可能都有偏见,但我希望有人花时间研究所有这些框架,并且至少进行了一般性的客观比较。
如果以前没有这样做,我非常愿意自己进行调查,但我认为至少有一些人已经这样做了。
如果您有多个DI / IoC容器的使用经验,请对这些容器的优缺点进行排序和总结,谢谢。这不是发现人们制作的所有模糊小容器的练习,我正在寻找流行(和主动)框架之间的比较。
答案 0 :(得分:220)
虽然这个问题的综合答案占用了数百页的my book,但这是一个我仍在努力的快速比较图表:
答案 1 :(得分:110)
我遇到了另一场演出comparison(2014年4月10日最新更新)。它比较了以下内容:
以下是帖子的简短摘要:
结论
Ninject绝对是最慢的容器。
MEF,LinFu和Spring.NET比Ninject更快,但仍然很漂亮 慢。接下来是AutoFac,Catel和Windsor,然后是StructureMap, Unity和LightCore。 Spring.NET的一个缺点是,这只能是 用XML配置。
SimpleInjector,Hiro,Funq,Munq和Dynamo提供最好的 性能,它们非常快。试一试!
特别简单的注射器似乎是一个不错的选择。它非常快,有一个很好的 文档,还支持拦截等高级场景 和通用装饰。
您也可以尝试使用Common Service Selector Library,并希望尝试多种选项,看看什么最适合您。
网站上有关公共服务选择器库的一些信息:
该库提供了对IoC容器和服务的抽象 定位器。使用该库允许应用程序间接访问 功能而不依赖于硬引用。希望是这样的 使用此库,可以开始第三方应用程序和框架 利用IoC /服务位置而不将自己束缚到a 具体实施。
13.09.2011: Funq和Munq已添加到参赛者名单中。图表也进行了更新,由于性能不佳,Spring.NET被删除了。
04.11.2011:“添加了Simple Injector,表现是所有选手中最好的”。
答案 2 :(得分:48)
请阅读Philip Mat的这篇伟大的.Net DI container comparison blog。
他做了一些彻底的性能比较测试;
答案 3 :(得分:29)
免责声明:截至2015年初,Jimmy Bogard对IoC Container 功能进行了大量比较,以下是摘要:
比较容器:
场景是这样的:我有一个界面,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 { }
我有兴趣看一些关于泛型容器支持的事情:
设置泛型差异(为基本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);
<强> 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;
}
<强>温莎强>
var container = new WindsorContainer();
container.Register(Classes.FromAssemblyContaining<IMediator>().Pick().WithServiceAllInterfaces());
container.Register(Classes.FromAssemblyContaining<Ping>().Pick().WithServiceAllInterfaces());
container.Kernel.AddHandlersFilter(new ContravariantFilter());
答案 4 :(得分:20)
实际上有大量的IoC框架。似乎每个程序员都试图在他们职业生涯的某个阶段写一个。也许不发表它,但要学习内部运作。
我个人更喜欢autofac,因为它非常灵活,并且具有适合我的语法(尽管我真的很讨厌所有寄存器方法都是扩展方法)。
其他一些框架:
答案 5 :(得分:6)
好吧,看看目前为止我发现的最佳比较是:
http://www.sturmnet.org/blog/2010/03/04/poll-ioc-containers-for-net
http://www.sturmnet.org/blog/2010/03/04/poll-results-ioc-containers-for-net
这是一项于2010年3月进行的民意调查。
我感兴趣的一点是那些使用DI / IoC框架并喜欢/不喜欢它的人,StructureMap似乎名列前茅。
同样从民意调查来看,似乎Castle.Windsor和StructureMap似乎最受青睐。
有趣的是,Unity和Spring.Net似乎是最受欢迎的热门选项。 (我正在考虑Unity的懒惰(以及微软徽章/支持),但我现在将更密切地关注Castle Windsor和StructureMap。)
当然这可能(?)不适用于2010年5月发布的Unity 2.0。
希望其他人可以根据直接经验提供比较。
答案 6 :(得分:5)
在我撰写此文时,请参阅列表中不包含linfu和spring.net的net-ioc-frameworks on google code的比较。
我在spring.net工作:它有很多功能(aop,库,文档......),并且在dotnet和java-world中有很多经验。功能模块化,所以你不必采取所有功能。这些功能是数据库抽象,loggingabstraction等常见问题的抽象。但是,进行和调试IoC配置是很困难的。
从我到目前为止所读到的内容:如果我必须选择一个小型或中型项目,我将使用ninject,因为ioc-configuration已完成并可在c#中调试。但我还没有使用它。对于大型模块化系统,由于抽象库,我将继续使用spring.net。