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

Ninject 团结 城堡。温莎 Autofac StructureMap

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

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

更新:

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

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

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

第二次更新:

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


当前回答

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

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似乎名列前茅。

从民调来看,卡塞尔。Windsor和StructureMap似乎是最受欢迎的。

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

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

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

其他回答

虽然对这个问题的全面回答占据了我书中数百页的篇幅,但这里有一个我仍在制作的快速比较图表:

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

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似乎名列前茅。

从民调来看,卡塞尔。Windsor和StructureMap似乎是最受欢迎的。

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

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

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

在我写这篇文章的时候,看看谷歌代码上的net-ioc-框架的比较,包括linfu和spring.net。

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

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

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

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

其他一些框架:

https://simpleinjector.org/ http://microioc.codeplex.com/ http://munq.codeplex.com/ http://funq.codeplex.com/

免责声明:截至2015年初,Jimmy Bogard对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 */ }

自发法克

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());

开放泛型:是的,隐式地 多重开放泛型:是的,隐式地 一般的矛盾性:是的,使用用户构建的扩展