Jak porównują się główne frameworki C # DI / IoC? [zamknięte]

Ryzykując wkroczenie na terytorium świętej wojny, jakie są mocne i słabe strony tych popularnych frameworków DI/IoC I czy można je łatwo uznać za najlepsze? ..:

  • Ninject
  • jedność
  • Zamek.Windsor
  • Autofac
  • StructureMap

Czy są jakieś inne frameworki DI / IoC dla C#, których tu nie wymieniłem?

W kontekście mojego przypadku użycia, buduję aplikację WPF klienta i infrastrukturę usług WCF/SQL, łatwość wykorzystanie (zwłaszcza pod względem jasnej i zwięzłej składni), spójna dokumentacja, dobre wsparcie społeczności i wydajność to ważne czynniki w moim wyborze.

Aktualizacja:

Przytoczone zasoby i zduplikowane pytania wydają się być nieaktualne, czy ktoś, kto zna wszystkie te frameworki, może się zgłosić i dać jakiś prawdziwy wgląd?

Zdaję sobie sprawę, że większość opinii na ten temat jest prawdopodobnie stronnicza, ale mam nadzieję, że ktoś poświęcił czas na przestudiowanie wszystkich te ramy i mają przynajmniej ogólnie obiektywne porównanie.

Jestem całkiem skłonny do prowadzenia własnych dochodzeń, jeśli tego nie robiono wcześniej, ale założyłem, że było to coś, co przynajmniej kilka osób już zrobiło.

Druga Aktualizacja:

Jeśli masz doświadczenie z więcej niż jednym kontenerem DI/IoC, oceń i podsumuj zalety i wady tych kontenerów, dziękuję. To nie jest ćwiczenie w odkrywaniu wszystkich niejasnych małych pojemników, które ludzie zrobili, Szukam porównań pomiędzy popularnymi (i aktywnymi) frameworkami.

Author: Mark Seemann, 2011-01-03

7 answers

Podczas gdy wyczerpująca odpowiedź na to pytanie zajmuje setki stron mojej książki, oto wykres szybkiego porównania, nad którym wciąż pracuję:

Tabela wyjaśniająca różnicę między kilkoma DIC

 209
Author: Mark Seemann,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-16 09:23:33

Natknąłem się na kolejne porównanie wydajności (ostatnia aktualizacja 10 kwietnia 2014). Porównuje on:

Oto krótkie podsumowanie postu:

Podsumowanie

Ninject jest zdecydowanie najwolniejszym kontenerem.

MEF, LinFu i Spring.NET są szybsze niż Ninject, ale nadal ładne powoli. AutoFac, Catel i Windsor, a następnie StructureMap, Jedność i LightCore. Wadą Spring.NET jest, że może być tylko skonfigurowany za pomocą XML.

SimpleInjector, Hiro, Funq, Munq i Dynamo oferują najlepsze wydajność, są niezwykle szybkie. Spróbuj!

Szczególnie prosty wtryskiwacz wydaje się być dobrym wyborem. Jest bardzo szybki, ma dobry dokumentacji, a także obsługuje zaawansowane scenariusze, takie jak przechwytywanie i zwykli dekoratorzy.

Możesz również spróbować użyć Common Service Selector Library i mam nadzieję, że spróbować wielu opcji i zobaczyć, co działa najlepiej dla Ciebie.

Trochę informacji o Bibliotece selektora usług Common Service ze strony:

Biblioteka udostępnia abstrakcję nad kontenerami i usługą IoC lokalizatory. Korzystanie z biblioteki umożliwia aplikacji pośredni dostęp możliwości bez opierania się na twardych referencjach. Nadzieja jest taka, że korzystanie z tej biblioteki, aplikacje i struktury innych firm mogą rozpocząć aby wykorzystać lokalizację IoC / usługi bez przywiązując się do konkretne wdrożenie.

Update

13.09.2011: Funq i Munq zostały dodane do listy uczestników. Wykresy zostały również zaktualizowane, a Spring.NET został usunięty ze względu na słabe osiągi.

04.11.2011: "dodano prosty wtryskiwacz , wydajność jest najlepsza ze wszystkich uczestników".

 109
Author: Pranav Shah,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-28 05:29:38

Po prostu przeczytaj ten świetny . Net DI kontenerowy blog porównawczy autorstwa Philipa Mata.

On robi kilka dokładnych testów porównawczych wydajności na;

Poleca Autofac ponieważ jest mały, szybki i łatwy w użyciu ... Zgadzam się. Wydaje się, że jedność i Ninject {[2] } są najwolniejsi w jego testach.

 47
Author: brodie,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-15 15:25:08

Od początku 2015 r., istnieje świetne porównanie IoC Container funkcje z Jimmy Bogard , Oto podsumowanie:

Porównane Kontenery:

  • Autofac
  • Ninject
  • Prosty Wtryskiwacz
  • StructureMap
  • jedność
  • Windsor

Scenariusz jest następujący: mam interfejs, IMediator, w którym mogę wysłać pojedyncze żądanie / odpowiedź lub powiadomienie do wielu odbiorcy:

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

Następnie utworzyłem podstawowy zestaw zapytań/odpowiedzi/powiadomień:

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

Byłem zainteresowany spojrzeniem na kilka rzeczy w odniesieniu do obsługi kontenerów dla leków generycznych:

    W przeciwieństwie do tego, w jaki sposób można uzyskać dostęp do Internetu]}
  • konfiguracja dla wielu rejestracji otwartych generyków (dwóch lub więcej INotificationHandlers)

Setup for generic variance (registration handlers for base INotification/creating request rurociągi) Moje manipulatory są dość proste, po prostu wychodzą na konsolę:

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();
  • open generics: yes, implicite
  • Multiple open generics: yes, implicite
  • kontrargument ogólny: tak, jawnie

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);
  • open generics: yes, implicite
  • Multiple open generics: yes, implicite
  • kontrargument ogólny: tak, z wbudowanym przez użytkownika rozszerzenia

Wtryskiwacz Prosty

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);
  • open generics: Yes, explicite
  • wiele otwartych generyków: tak, jawnie
  • W przeciwieństwie do wersji 3.0, Wersja 3.0 jest dostępna tylko w wersji 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<>));
    });
});
  • open generics: Yes, explicite
  • wiele otwartych generyków: tak, jawnie
  • kontrawariancja Ogólna: tak, implicite

Jedność

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;
}
  • open generics: yes, implicite
  • wiele otwartych generyków: tak, z rozszerzeniem wbudowanym przez użytkownika
  • kontrargument ogólny: derp

Windsor

var container = new WindsorContainer();
container.Register(Classes.FromAssemblyContaining<IMediator>().Pick().WithServiceAllInterfaces());
container.Register(Classes.FromAssemblyContaining<Ping>().Pick().WithServiceAllInterfaces());
container.Kernel.AddHandlersFilter(new ContravariantFilter());
  • open generics: yes, implicite
  • Multiple open generics: yes, implicite
  • kontrargument ogólny: tak, z rozszerzeniem wbudowanym przez użytkownika
 28
Author: stratovarius,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-12 18:57:29

W rzeczywistości jest mnóstwo frameworków MKOl. Wygląda na to, że każdy programista próbuje go napisać w pewnym momencie swojej kariery. Może nie po to, by ją opublikować, ale po to, by poznać wewnętrzne funkcjonowanie.

Osobiście wolę autofac, ponieważ jest dość elastyczny i ma składnię, która mi odpowiada (chociaż naprawdę nienawidzę, że wszystkie metody rejestru są metodami rozszerzeń).

Inne Framework:

 20
Author: jgauffin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-29 15:10:03

Cóż, po obejrzeniu najlepszego porównania jakie do tej pory znalazłem to:

Ankieta przeprowadzona w marcu 2010 roku.

Jedną z ciekawostek jest to, że ludzie, którzy używali frameworka DI / IoC I lubili/nie lubili Go, StructureMap wydaje się wychodzić na top.

Również z sondażu wynika, że Zamek.Windsor i StructureMap wydają się być najbardziej preferowane.

Ciekawe, jedność i Spring.Net wydają się być popularne opcje, które są najczęściej nielubiane. (Rozważałem Unity z lenistwa (i Microsoft badge/support), ale przyjrzę się teraz dokładniej Castle Windsor i StructureMap.)

Oczywiście to prawdopodobnie (?) Nie dotyczy Unity 2.0, która była wydany w maju 2010 roku.

Mam nadzieję, że ktoś inny może dostarczyć porównanie oparte na bezpośrednim doświadczeniu.

 6
Author: ocodo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-03 10:09:56

Zobacz porównanie NET-ioc-frameworków na Google code w tym linfu i spring.net których nie ma na twojej liście, kiedy piszę ten tekst.

I worked with spring.net: posiada wiele funkcji (AOP, libraries , docu, ...) i jest z tym duże doświadczenie w dotnet i java-świecie. Funkcje są modularne, więc nie musisz brać wszystkich funkcji. Funkcje są abstrakcjami typowych problemów, takich jak databaseabstraction, loggingabstraction. jakkolwiek jest trudno zrobić i debugować konfigurację IoC.

Z tego co do tej pory czytałem: gdybym miał wybrać dla małego lub średniego projektu użyłbym ninject, ponieważ ioc-konfiguracja jest wykonywana i debugowana w c#. Ale jeszcze z nim nie pracowałem. dla dużego systemu modułowego zostałbym z spring.net ze względu na abstrakcję-biblioteki.

 5
Author: k3b,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-03 05:35:06