oco*_*odo 298 c# dependency-injection ninject ioc-container unity-container
冒着进入神圣战争领域的风险,这些流行的DI/IoC框架有哪些优点和缺点,可以轻松地被认为是最好的?..:
我还没有列出其他用于C#的DI/IoC框架吗?
在我的用例的上下文中,我正在构建一个客户端WPF应用程序,一个WCF/SQL服务基础架构,易用性(特别是在清晰简洁的语法方面),一致的文档,良好的社区支持和性能都是重要因素在我的选择.
所引用的资源和重复问题似乎已经过时,那些了解所有这些框架的人能否提出并提供一些真正的见解?
我意识到关于这个主题的大多数意见可能都有偏见,但我希望有人花时间研究所有这些框架,并且至少进行了一般性的客观比较.
如果以前没有这样做,我非常愿意自己进行调查,但我认为至少有一些人已经这样做了.
如果您有多个DI/IoC容器的使用经验,请对这些容器的优缺点进行排序和总结,谢谢.这不是发现人们制作的所有模糊小容器的练习,我正在寻找流行(和主动)框架之间的比较.
Mar*_*ann 223
虽然对这个问题的全面回答占用了我书的数百页,但这是一个我仍在研究的快速比较图表:
Pra*_*hah 113
我遇到了另一个性能比较(最新更新2014年4月10日).它比较了以下内容:
以下是帖子的快速摘要:
结论
Ninject绝对是最慢的容器.
MEF,LinFu和Spring.NET比Ninject快,但仍然很慢.接下来是AutoFac,Catel和Windsor,其次是StructureMap,Unity和LightCore.Spring.NET的一个缺点是,只能用XML配置.
SimpleInjector,Hiro,Funq,Munq和Dynamo提供最佳性能,它们非常快.试一试!
特别简单的注射器似乎是一个不错的选择.它非常快,具有良好的文档,并且还支持拦截和通用装饰器等高级场景.
您也可以尝试使用公共服务选择器库,并希望尝试多个选项,看看什么最适合您.
从网站上获得有关公共服务选择器库的一些信息:
该库提供了IoC容器和服务定位器的抽象.使用该库允许应用程序间接访问功能,而不依赖于硬引用.希望使用此库,第三方应用程序和框架可以开始利用IoC /服务位置,而无需将自己与特定实现联系起来.
13.09.2011: Funq和Munq被添加到参赛者名单中.图表也进行了更新,Spring.NET由于性能不佳而被删除.
04.11.2011: "添加了Simple Injector,性能是所有参赛者中最好的".
bro*_*die 49
请阅读Philip Mat撰写的这篇伟大的.Net DI容器比较博客.
他做了一些彻底的性能比较测试;
他建议使用Autofac,因为它小巧,快速且易于使用......我同意.Unity和Ninject似乎是他测试中最慢的.
str*_*ius 31
免责声明:自2015年年初,有一个IoC容器有很大的比较功能,从吉米·博加德,这里是一个总结:
比较容器:
该方案是这样的:我有一个接口,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;
}
Run Code Online (Sandbox Code Playgroud)
然后我创建了一组基本的请求/响应/通知:
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 { }
Run Code Online (Sandbox Code Playgroud)
我有兴趣看一些关于泛型容器支持的事情:
通用方差的设置(注册基本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 */ }
Run Code Online (Sandbox Code Playgroud)
Autofac
var builder = new ContainerBuilder();
builder.RegisterSource(new ContravariantRegistrationSource());
builder.RegisterAssemblyTypes(typeof (IMediator).Assembly).AsImplementedInterfaces();
builder.RegisterAssemblyTypes(typeof (Ping).Assembly).AsImplementedInterfaces();
Run Code Online (Sandbox Code Playgroud)
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);
Run Code Online (Sandbox Code Playgroud)
简单的注射器
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);
Run Code Online (Sandbox Code Playgroud)
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<>));
});
});
Run Code Online (Sandbox Code Playgroud)
统一
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;
}
Run Code Online (Sandbox Code Playgroud)
温莎
var container = new WindsorContainer();
container.Register(Classes.FromAssemblyContaining<IMediator>().Pick().WithServiceAllInterfaces());
container.Register(Classes.FromAssemblyContaining<Ping>().Pick().WithServiceAllInterfaces());
container.Kernel.AddHandlersFilter(new ContravariantFilter());
Run Code Online (Sandbox Code Playgroud)
jga*_*fin 21
实际上有大量的IoC框架.似乎每个程序员都试图在他们职业生涯的某个阶段写一个.也许不发表它,但要学习内部运作.
我个人更喜欢autofac,因为它非常灵活,并且具有适合我的语法(尽管我真的很讨厌所有寄存器方法都是扩展方法).
其他一些框架:
那么,看看我迄今发现的最佳比较是:
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.
希望其他人可以根据直接经验提供比较.
在我写这篇文章时,请参阅google代码上的net-ioc-frameworks的比较,包括linfu和spring.net.
我在spring.net工作:它有很多功能(aop,库,文档......),并且在dotnet和java-world中有很多经验.功能模块化,所以你不必采取所有功能.这些功能是数据库抽象,loggingabstraction等常见问题的抽象.但是,进行和调试IoC配置是很困难的.
从我到目前为止所读到的内容:如果我必须选择一个小型或中型项目,我将使用ninject,因为ioc-configuration已完成并可在c#中调试.但我还没有使用它.对于大型模块化系统,由于抽象库,我会留在spring.net.
归档时间: |
|
查看次数: |
102574 次 |
最近记录: |