2009-08-17 13 views
64

Patrząc na Microsoft Managed Extensibility Framework (MEF) i różne kontenery IoC (takie jak Unity), nie widzę, kiedy stosować jeden typ rozwiązania w stosunku do drugiego. Dokładniej, wydaje się, że MEF obsługuje większość wzorców typu IoC i że kontener IoC taki jak Unity nie byłby tak potrzebny.MEF vs. dowolne IoC

Idealnie byłoby, gdybym użył kontenera IoC zamiast MEF lub oprócz niego.

+0

Powiązane pytanie [tutaj] (http://stackoverflow.com/questions/411660/enterprise-library-unity-vs-other-ioc-containers) – Benjol

Odpowiedz

72

Podstawowa różnica polega na tym, że pojemniki IoC są na ogół najbardziej przydatne w przypadku zależności statycznych (znanych w czasie kompilacji), a MEF jest na ogół najbardziej przydatny w przypadku zależności dynamicznych (znanych tylko w czasie wykonywania).

Jako takie, są one zarówno silniki kompozycji, ale nacisk jest bardzo różny dla każdego wzoru. Decyzje projektowe są zatem bardzo zróżnicowane, ponieważ MEF jest zoptymalizowany w odniesieniu do odkrywania nieznanych części, a nie rejestrowania znanych części.

Pomyśl o tym w ten sposób: jeśli tworzysz całą swoją aplikację, pojemnik IoC jest prawdopodobnie najlepszy. Jeśli piszesz o rozszerzalności, tak, że zewnętrzni programiści będą rozszerzać twój system, MEF jest prawdopodobnie najlepszy.

Również artykuł w odpowiedzi @Pavel Nikolov zapewnia świetny kierunek (napisał Glenn Block, menedżer programu MEF).

+2

Ten artykuł MSDN naprawdę doprowadził punkt do domu dla mnie: http://msdn.microsoft.com/en-us/library/hh708870.aspx. Dla nowicjusza MEF znającego IoC/ID, MEF wydaje się być iniekcją (kompozycją) ... bez rejestracji typu. Tak więc powyższa odpowiedź na pytanie "tak" doprowadza mnie do punktu. Słuchając teraz szeroko reklamowanego odcinka podcastu Hanselmana na temat: http://www.hanselminutes.com/148/mef-managed-extensibility-framework-with-glenn-block – NovaJoe

+0

Proszę wskazać kilka konkretnych przykładów gdzie IoC byłoby bardziej przydatne przy statycznych zależnościach (znanych w czasie kompilacji) niż MEF. Uważam, że atrybuty Export \ Import Attribute lub Registration Builder są bardziej przydatne w przypadku zależności statycznych niż skomplikowane pliki konfiguracyjne powodujące błędy. –

+1

@AaronStainback: Moim ulubionym pojemnikiem jest Autofac, który preferuje rejestrację opartą na kodzie nad plikami konfiguracyjnymi, podobnie jak w przypadku Buildera rejestracji (nie lubię XML). Zalety Autofac nad MEF obejmują: rejestrację za pomocą wyrażeń lambda, drobnoziarnistą kontrolę życia i ignorancję kompozycji (złożone typy nie potrzebują wiedzy o Autofac ani kontekście, w którym są używane). Aspekty te są najbardziej korzystne, gdy kontrolujesz złożone typy, stąd różnice w nacisku między Autofac i MEF. Diagram Venna pomiędzy tymi dwoma ogólnie obejmuje prostsze scenariusze DI. –

1

Zgadzam się, że MEF może być w pełni funkcjonalną strukturą IoC. Właściwie to piszę teraz aplikację opartą na używaniu MEF dla rozszerzalności i IoC. Wziąłem ogólne części i zrobiłem to w "ramach" i otworzyłem je jako własną strukturę o nazwie SoapBox Core, na wypadek, gdyby ludzie chcieli zobaczyć, jak to działa.

W szczególności zobacz, jak działa Host, jeśli chcesz zobaczyć MEF w akcji.

26

Używam MEF od jakiegoś czasu, a kluczowym czynnikiem, kiedy używamy go zamiast produktów IOC jest to, że regularnie mamy 3-5 implementacji danego interfejsu, który znajduje się w naszym katalogu wtyczek w danym czasie. Którą z tych implementacji należy użyć, jest to coś, o czym można zadecydować tylko w czasie wykonywania.

MEF dobrze sobie z tym radzi. Zazwyczaj IOC jest nastawiony na upewnienie się, że w pewnym momencie w przyszłości można wymieniać IUserRepository na podstawie produktu ORM 1 dla produktu ORM 2. Jednak większość rozwiązań IOC zakłada, że ​​w danym czasie będzie tylko jedna IUserRepository.

Jeśli jednak trzeba wybrać jeden na podstawie danych wejściowych dla danego żądania strony, kontenery IOC zazwyczaj tracą.

Jako przykład, sprawdzamy nasze uprawnienia i zatwierdzamy przez wtyczki MEF dla dużej aplikacji internetowej, nad którą pracowałem od dłuższego czasu. Korzystając z MEF, możemy przyjrzeć się, kiedy data utworzenia CreatedOn, i wykopać wtyczkę do sprawdzania poprawności, która faktycznie obowiązywała podczas tworzenia rekordu i uruchomić rekord BOTH za pośrednictwem tej wtyczki ORAZ walidatora, który jest aktualnie w użyciu i porównać ważność rekordu czas.

Ten rodzaj mocy pozwala również zdefiniować pominięcia dla wtyczek. Aplikacje, nad którymi pracuję, są właściwie tym samym wdrożeniem kodu dla 30+ implementacji. Tak więc zazwyczaj szukamy wtyczek, prosząc o:

  1. Implementacja interfejsu, która jest specyficzna dla bieżącej witryny i określonego typu rekordu.
  2. Implementacja interfejsu, która jest specyficzna dla bieżącej witryny, ale działa z dowolnym typem rekordu.
  3. Interfejs działający dla dowolnej witryny i dowolnego rekordu.

Pozwala to na dołączenie zestawu domyślnych wtyczek, które zostaną uruchomione, ale tylko wtedy, gdy ta konkretna implementacja nie zastąpi go regułami specyficznymi dla klienta.

IOC to świetna technologia, ale wydaje się, że chodzi o ułatwienie kodowania na interfejsy zamiast konkretnych implementacji. Jednak zamiana tych implementacji jest raczej wydarzeniem typu przesunięcie projektu w IOC. W programie MEF można elastycznie korzystać z interfejsów i konkretnych implementacji, co sprawia, że ​​jest to decyzja dotycząca wykonywania wielu różnych opcji.

+0

Podoba mi się przykład zastosowania wielu walidacji za pośrednictwem MEF. –

5

Przepraszam za bycie nie na temat. Chciałem po prostu powiedzieć, że są 2 wady, które czynią MEF niepotrzebną komplikację:

  • jest atrybut oparty który nie robi nic dobrego do pomaga zastanawianie się, dlaczego to działa tak jak oni. Nie ma sposobu, aby dotrzeć do detali osadzonych w elementach szkieletu, aby zobaczyć, co dokładnie się tam dzieje. Nie ma sposobu, aby uzyskać log śledzenia lub podłączyć się do mechanizmów rozwiązywania problemów i obsługiwać nierozwiązane sytuacje ręcznie

  • to nie ma żadnego mechanizmu rozwiązywania problemów, aby dowiedzieć się, dlaczego niektóre części są odrzucane. Pomimo wskazania części, która zawodzi, nie powie Ci ona, dlaczego ta część się nie powiodła.

Jestem bardzo rozczarowany. Spędziłem zbyt wiele czasu walcząc z wiatrakami, próbując załadować kilka klas, zamiast pracować nad prawdziwymi problemami. Przekonałem się, że nie ma nic lepszego niż technika wtrysku zależnego od starej szkoły, kiedy masz pełną kontrolę nad tym, co jest tworzone, kiedy i możesz śledzić cokolwiek w debugerze VS. Chciałbym, żeby ktoś, kto jest zwolennikiem MEF, przedstawił kilka dobrych powodów, dlaczego wybrałbym to na zwykłym DI.