Enterprise Library Unity a inne kontenery IoC [zamknięte]

135

Jakie są zalety i wady korzystania z Enterprise Library Unity w porównaniu z innymi kontenerami IoC (Windsor, Spring.Net, Autofac ..)?

Yoann. b
źródło
9
Tego typu pytania są zawsze zamknięte. Opinie są ważne. Czy jest miejsce, gdzie je umieścić?
Jeson Martajaya
1
@JesonMartajaya, chciałem pochwalić dokładnie ten sam komentarz, denerwujące jest to, że pytania się zamykają, ale brak odpowiedzi na alternatywę.
Mohammed Noureldin

Odpowiedzi:

234

Przygotowuję prezentację dla grupy użytkowników. Jako taki właśnie przeszedłem przez kilka z nich. Mianowicie: AutoFac, MEF, Ninject, Spring.Net, StructureMap, Unity i Windsor.

Chciałem pochwalić się przypadkiem 90% (wstrzyknięcie konstruktora, do którego i tak ludzie używają głównie IOC). Możesz sprawdzić rozwiązanie tutaj (VS2008)

W związku z tym istnieje kilka kluczowych różnic:

  • Inicjalizacja
  • Pobieranie obiektów

Każdy z nich ma również inne funkcje (niektóre mają AOP i lepsze gadżety, ale generalnie wszystko, czego chcę, aby IOC robił, to tworzenie i pobieranie obiektów dla mnie)

Uwaga: różnice między różnymi pobieranymi obiektami bibliotek można zanegować za pomocą CommonServiceLocator: http://www.codeplex.com/CommonServiceLocator

Pozostaje nam więc inicjalizacja, która odbywa się na dwa sposoby: za pomocą kodu lub konfiguracji XML (app.config / web.config / custom.config). Niektórzy obsługują oba, inni tylko jeden. Powinienem zauważyć: niektórzy używają atrybutów, aby pomóc IoC.

Oto moja ocena różnic:

Ninject

Tylko inicjalizacja kodu (z atrybutami). Mam nadzieję, że lubisz lambdy. Kod inicjujący wygląda następująco:

 IKernel kernel = new StandardKernel(
                new InlineModule(
                    x => x.Bind<ICustomerRepository>().To<CustomerRepository>(),
                    x => x.Bind<ICustomerService>().To<CustomerService>(),
                    x => x.Bind<Form1>().ToSelf()
                    ));

Mapa struktury

Kod inicjalizacji lub XML lub atrybuty. wersja 2.5 jest również bardzo lambda'y. Podsumowując, jest to jeden z moich ulubionych. Kilka bardzo interesujących pomysłów dotyczących wykorzystania atrybutów przez StructureMap.

ObjectFactory.Initialize(x =>
{
    x.UseDefaultStructureMapConfigFile = false;
    x.ForRequestedType<ICustomerRepository>()
        .TheDefaultIsConcreteType<CustomerRepository>()
        .CacheBy(InstanceScope.Singleton);

    x.ForRequestedType<ICustomerService>()
        .TheDefaultIsConcreteType<CustomerService>()
        .CacheBy(InstanceScope.Singleton);

    x.ForConcreteType<Form1>();
 });

Jedność

Kod inicjujący i XML. Niezła biblioteka, ale konfiguracja XML jest bardzo upierdliwa. Świetna biblioteka dla firmy Microsoft lub sklepów przy autostradach. Inicjalizacja kodu jest łatwa:

 container.RegisterType<ICustomerRepository, CustomerRepository>()
          .RegisterType<ICustomerService, CustomerService>();

Spring.NET

XML tylko tak blisko, jak potrafię. Ale jeśli chodzi o funkcjonalność, Spring.Net robi wszystko pod słońcem, co może zrobić IoC. Ale ponieważ jedynym sposobem na ujednolicenie jest użycie XML, jest to generalnie unikane przez sklepy .net. Chociaż wiele sklepów .net / Java używa Spring.Net ze względu na podobieństwo między wersją .net Spring.Net i projektem Java Spring.

Uwaga : konfiguracja w kodzie jest teraz możliwa dzięki wprowadzeniu Spring.NET CodeConfig .

Windsor

XML i kod. Podobnie jak Spring.Net, Windsor zrobi wszystko, co chcesz. Windsor to prawdopodobnie jeden z najpopularniejszych kontenerów IoC w okolicy.

IWindsorContainer container = new WindsorContainer();
container.AddComponentWithLifestyle<ICustomerRepository, CustomerRepository>("CustomerRepository", LifestyleType.Singleton);
container.AddComponentWithLifestyle<ICustomerService, CustomerService>("CustomerService",LifestyleType.Singleton);
container.AddComponent<Form1>("Form1");

Autofac

Może łączyć XML i kod (z wersją 1.2). Ładna, prosta biblioteka IoC. Wydaje się, że podstawy nie wymagają większego zamieszania. Obsługuje zagnieżdżone kontenery z lokalnym określaniem zakresu komponentów i dobrze zdefiniowanym zarządzaniem czasem życia.

Oto jak go zainicjować:

var builder = new ContainerBuilder();
builder.Register<CustomerRepository>()
        .As<ICustomerRepository>()
        .ContainerScoped();
builder.Register<CustomerService>()
        .As<ICustomerService>()
        .ContainerScoped();
builder.Register<Form1>();

Gdybym miał dziś wybierać: prawdopodobnie wybrałbym StructureMap. Ma najlepszą obsługę funkcji języka C # 3.0 i największą elastyczność w inicjalizacji.

Uwaga : Chris Brandsma przekształcił swoją oryginalną odpowiedź w post na blogu .

Chris Brandsma
źródło
1
Tylko konfiguracja XML, co znacznie utrudnia konfigurację. Zasadniczo jedynymi osobami, które widzę, które chcą używać Spring.Net, są byli programiści Java.
Chris Brandsma
Chris, odnosząc się do twoich wniosków: czy możesz podać więcej szczegółów na temat a) funkcji C # 3, do których się odnosisz, b) jakie rodzaje inicjalizacji są dla Ciebie ważne? Dzięki!
Nicholas Blumhardt
2
Cześć Nicholas: jeśli chodzi o obsługę C # 3, wszystko, co robi już Autofac. :) Do inicjalizacji potrzebuję łatwego wsparcia dla singletonów / nie singletonów i inicjalizacji na sesję. Na koniec chcę łatwych sposobów odwoływania się za pomocą niestandardowej nazwy. (coś, co jest PITA w StructureMap). Ostatnia funkcja, która mi się teraz podoba bardziej niż wtedy, gdy pisałem to pierwotnie: AutoMocking. Nie używam go cały czas, ale bardzo miło jest mieć arount.
Chris Brandsma
Wspomniałeś również o MEF, używam MEF do dostarczania moich obiektów implementacji IRepository i stwierdzam, że działa dobrze. Co myślisz o MEF?
terjetyl
Oto fajny, 20-minutowy screencast przedstawiający większość Unity: pnpguidance.net/Screencast/ ...
Pat
7

O ile widziałem, są prawie takie same, z wyjątkiem kilku szczegółów implementacji tu i tam. Największą przewagą Unity nad konkurencją jest to, że jest dostarczany przez Microsoft, jest wiele firm, które boją się OSS.

Wadą jest to, że jest raczej nowy, więc może zawierać błędy, które starsi gracze już rozwiązali.

Powiedziawszy to, możesz to sprawdzić .

rodbv
źródło
4

Stary wątek, ale ponieważ jest to pierwsza rzecz, którą Google pokazał mi, kiedy wpisałem unity vs spring.net ...

Spring robi teraz CodeConfig, jeśli nie lubisz konfiguracji XML

http://www.springframework.net/codeconfig/doc-latest/reference/html/

Ponadto Spring to znacznie więcej niż tylko kontener DI, jeśli spojrzysz na sekcję „Moduły” w dokumentacji, kontener DI jest podstawą ogromnego stosu rzeczy, które robi.

Richard
źródło
3

Popraw mnie, jeśli się mylę, ale myślę, że sam Autofac obsługuje konfigurację XML wymienioną w tym linku: Konfiguracja Autofac XML


źródło
2

Spring ma jedną cechę, że może wstrzyknąć parametry do konstruktora lub właściwości na podstawie nazwy lub pozycji parametru. Jest to bardzo przydatne, jeśli parametr lub właściwość jest typu prostego (np. Liczba całkowita, wartość logiczna). Zobacz przykład tutaj . Nie sądzę, aby to naprawdę nadrabiało niezdolność Springa do wykonania konfiguracji w kodzie.

Windsor również może to zrobić i może to zrobić w kodzie, a nie w konfiguracji. (popraw mnie, jeśli się mylę, przechodzę przez to, co tutaj słyszałem).

Chciałbym wiedzieć, czy Unity może to zrobić.

Anthony
źródło
2

Jedna uwaga: Ninject to jedyny kontener IoC, który obsługuje kontekstowe iniekcje zależności (zgodnie z ich witryną internetową). Jednak ponieważ nie mam doświadczenia z innymi kontenerami IoC, nie mogę powiedzieć, czy to się zgadza.

ehsanullahjan
źródło
Jeśli to wszystko „kontekstowe wstrzyknięcie zależności” jest w Ninject, to… uhh, nic specjalnego. Obsługiwane (na różne sposoby) przynajmniej w Unity, AutoFac, Windsor.
user2864740
1

Aby dodać moje 2 centy, wypróbowałem zarówno StructureMap, jak i Unity. Zauważyłem, że StructureMap jest słabo / błędnie udokumentowany, trudny do skonfigurowania i niezgrabny w użyciu. Podobnie wydaje się, że nie obsługuje scenariuszy, takich jak przesłonięcie argumentów konstruktora w czasie rozwiązywania, co było dla mnie kluczowym punktem użycia. Więc rzuciłem to i poszedłem z Unity i zrobiłem to, co chciałem w około 20 minut.

Jacobs Data Solutions
źródło
1

Osobiście używam Unity, ale tylko dlatego, że pochodzi od firmy Microsoft. Żałuję tej decyzji z jednego powodu: największa rzecz, jaką ma przeciwko niej, ma jeden duży „błąd”, który powoduje, że nieustannie rzuca wyjątki. Możesz zignorować wyjątki podczas debugowania. Jednak spowalnia swoją aplikację ogromnie jeśli natknąć się nim, ponieważ rzuca wyjątek jest kosztowna operacja. Na przykład, obecnie „naprawiam” ten wyjątek w jednym miejscu w moim kodzie, gdzie wyjątki Unity dodają dodatkowe 4 sekundy do czasu renderowania strony. Aby uzyskać więcej informacji i obejść, zobacz:

Czy można sprawić, aby Unity nie zgłaszał wyjątku SynchronizationLockException przez cały czas?

Josh Mouch
źródło
Dzięki za ostrzeżenie! Zgodnie z tą odpowiedzią z pytania, o którym mówiłeś , błąd został rozwiązany.
Sam
Dlaczego Unity rzuca wyjątek? Zwykle wyjątkiem jest „błąd krytyczny” (taki jak nierozwiązywalna zależność), a nie coś, co należy stłumić.
user2864740
Przepraszam, czy ten „błąd” został rozwiązany, czy też znalazłeś sposób, aby go uniknąć? Wybieram teraz framework w c # .net i chciałbym wiedzieć, czy jedność to nadal koszt czasu ...
Jog Dan