rozszerzalne aplikacje w .net(czyli maf i mef)
TRANSCRIPT
Rozszerzalne aplikacje w .NET
(czyli MAF i MEF)Autor: Maciej Zbrzezny
Łódzka Grupa Profesjonalistów IT & .NET
Study Group "Architektura oprogramowania"
O mnie− Nazywam się Maciej Zbrzezny − Pracuje w firmie Rule Financial. − Tworzę oprogramowanie
wykorzystujące platformę .NET(głównie C#).
− Autor bloga „Programowanie i Technologie” (http://maciej-progtech.blogspot.com/).
− MCPD Windows Developer 4.0 − MCTS ASP.NET 3.5. − [email protected] − @MaciejZbrzezny
ROZSZERZALNOŚĆ PRZEDE WSZYSTKIM!
Po co to wszystko?
Rozszerzalność – pożądana
− Deweloperzy, architekci oprogramowania od zawsze myślą o tym:− By ich aplikacje były rozszerzalne− By można było dodawać nowe elementy
bez potrzeby ich ponownej rekompilacji− By aplikację można było rozszerzać łatwo
i bez dużego nakładu pracyWtyczki (lub też: Add-In, Add-On, Rozszerzenie, Extension, Komponent , Plug-In, Snap-In, ...)
Brak standardu
− Firefox (dlaczego stał się taki popularny? Dlaczego Opera traciła?)
− Office ma swój model – ale tylko dla Office’a
− ASP.NET ma swój dzięki provider’om
− SharpDevelop - SODA− …
Uproszczona architektura
Host
Komponent
Host
Komponent(?
wtyczka/plugin ?)
Kontrakt
Interfejsy, czyli wstęp do plugin’ów
Interfejs (kontrakt):
Implementacja interfejsu (plugin):
http://maciej-progtech.blogspot.com/2010/05/jak-zaimplementowac-mechanizm-wtyczek.html
Prosty host dla pluginów …
http://maciej-progtech.blogspot.com/2010/05/jak-zaimplementowac-mechanizm-wtyczek.htmlhttp://maciej-progtech.blogspot.com/2010/05/bezpieczne-wykorzystanie-obcych.html
Gotowy program:
Wady opisanego podejścia
− Brak obsługi błędów, − Prymitywne wyszukiwanie wtyczek
(discovery) − Brak identyfikacji i zarządzania
wtyczkami− Nie ma wyładowania (unload) wtyczek− Problemy przy zmianie kontraktu − …
Lepiej wykorzystać coś gotowego!
MAFSystem.AddIn
MAF
−Managed
−Add-in
−Framework
System.AddIn
Host views of add-ins
MAF filozofia (architektura ?)
Contract
Host
Komponent
Kontrakt
Add-in views
Host-side adapters
Add-ins-side adapters
Host
Add-in
Host
Host views of add-ins Host-side adapters
[HostAdapter]
Add-in-side adapters[AddInAdapter]
Add-in views[AddInBase]
Add-in[AddIn]
Contracts[AddInContract],
Interfaces only, inherits from IContract
MAF – elementy składowe• Host – aplikacja główna• Host view o add-ins – czyli
interfejsy, przez które aplikacja widzi swoje rozszerzenia,
• Host side adapters – czyli adaptery dostosowujące wspomniane interfejsy widoki do aktualnego kontraktu)
• Contracts – czyli interfejs (kontrakt) , na którym oparta jest współpraca,
• Add-in side adapters – czyli adaptery dostosowujące wspomniany kontrakt do widoku od strony wtyczki.
• Add-in view – konkretne interfejsy, na których oparte są wtyczki.
• Add-in – wtyczka, rozszerzenie, plugin …
MAF – struktura katalogówPipeline root
HostSideAdapters
Contracts
AddInSideAdapters
AddIns
Add-in A
AddInViews
Additional Add -Ins
Add-in X
Add-in Y
Required folder names
No subdirectories are allowed
Optional AddInPaths parameter of FindAddIns
Add-in B
Gdyby ktoś chciał coś zmienić:• The assembly "C:\(…)\
AddIns\DoSthV1SampleString\MAFSAmple1.Plugin.View.dll" should not be in location "C:\(…) :\(…)\AddIns\DoSthV1SampleString\". Remove it to avoid loader context problems.
• AddInSegmentDirectoryNotFoundException: The required folder "(...)\AddInSideAdapters" does not exist.
MAF ładowanie wtyczek String pipelineInRoot = Environment.CurrentDirectory; string[] warnings = AddInStore.Rebuild( pipelineInRoot );
Collection<AddInToken> tokens = AddInStore.FindAddIns( typeof( IDoSthAppView ), pipelineInRoot ); if ( tokens.Count > 0 ) { foreach ( var token in tokens ) { IDoSthAppView plugin = token.Activate<IDoSthAppView> ( AddInSecurityLevel.Host ); Console.WriteLine( "Message from plugin: {0}", plugin.DoSth( "Passed parameter" ) ); } }
Tworzenie store’a (pliki)
Wsparcie dla izolacji: Internet, Intranet,
FullTrust, Host
ĆWICZENIEMAF w praktyce …
MAF wady/zalety− Skomplikowane− Sztywna konstrukcja+ Możliwość uruchomienia pluginów w
środowisku izolowanym (inna AppDomain, inny proces)
+ Rozwiązuje problemy z kompatybilnością Host – plugin
+ Lifetime management+ Dobra dokumentacja w MSDN+ Jest częścią .NET 3.5
MAF – gdzie szukać informacji− MSDN: http://
msdn.microsoft.com/en-us/library/bb384241%28v=vs.90%29.aspx
− System.AddIn Tools and Samples on Codeplex: http://clraddins.codeplex.com/
− Channel9: http://channel9.msdn.com/Blogs/DanielMoth/Managed-AddIn-Framework, http://channel9.msdn.com/Blogs/DanielMoth/Version-Resilience-in-the-Managed-AddIn-Framework
− MSDN Magazine: http://msdn.microsoft.com/en-us/magazine/cc163476.aspx oraz http://msdn.microsoft.com/en-us/magazine/cc163460.aspx.
MEFSystem.ComponentModel.Composition
Rozszerzalność może być pułapką− Trudno osiągnąć,
a często jeszcze trudniej używać
− Rozszerzalność powinna być prosta
MEF−Managed
−Extensibility
−Framework
−Makes
−Extensibility
−Fun
IOC / DIMEF to nie tylko pluginy!
IoC / DI – o co chodzi?
− Masz problem – odwróć zależności.− Coraz popularniejsze staje się
wykorzystanie wzorców bazujących na Dependency Injection (DI) i Inversion Of Control (IoC)
− Zasada odwracania zależności:− Moduły wysokopoziomowe nie powinny
zależeć od niskopoziomowych (obie grupy niech zależą od abstrakcji)
− Abstrakcje nie powinny zależeć od szczegółowych rozwiązań (a na odwrót)
IoC / DI
− MEF skupia się na rozszerzalności aplikacji ale może być też wykorzystany do czegoś innego.
− MEF używa DI/IoC jako strategii pozwalającej na komponowanie różnych rozszerzeń, ale nie jest typowym generycznym kontenerem DI /IoC.
Przykład MEF dla DI/IOC
Zdekomponowana aplikacja
Interfejs użytkownika
MEFDI/IOC
Obiekty Biznesowe
WarstwaDostępu doDanych
Wnętrze aplikacji(wszystkie komponenty znane)
Na zewnątrz aplikacji(komponenty nie znane)
MEFDI/IOC
Dostawca danych zSQL Server
Dostawca danych zOracle Server
MEFImport
MEF a kontener IoC - różnice
MEF−Odkrywanie (Discovery)−Otwarte zestawy−Wiązania części z
zestawu, możliwość rekompozycji
−Brak zewnętrznej konfiguracji
Kontener IoC− Rejestracja− Zamknięte zestawy− Wiązania ścisłe− Zwykle zewnętrzna
konfiguracja− Zwykle szybszy niż MEF
Dlaczego i jak powstał?− Microsoft o dawna myślał: „Jak tworzyć aplikacje z
wielo-używalnych (resuable) komponentów, które mogą być odkrywane, używane i składane dynamicznie”?:− Visual Studio 2010 i nowy rozszerzalny edytor dla
programisty.− „Oslo” i edytor „Intellipad”, który korzysta z MEF, by
zapewnić rozszerzalność w oparciu o skrypty (pluginy) napisane w IreonPython’nie
− „Acropolis” i framework wspierający budowanie aplikacji kompozytowych, podczas działania odkrywane były komponenty aplikacji i związane z nimi serwisy, a do konfiguracji wykorzystywany XAML.
− Problem rozszerzalności nie dotyczył tylko Microsoftu. Konsumenci-programiści od lat sami implementowali własne mechanizmy rozszerzeń. Microsoft postanowił jednak zrobić krok i wyjść naprzód swoim i innych potrzebom.
Dlaczego potrzebujemy czegoś nowego?
− MEF nie jest pierwszym rozwiązaniem, który wspiera wspomniane wcześniej funkcjonalności. Było i jest wiele proponowanych rozwiązań:− Java: EJB, CORBA, OSGI w Eclipse (czyli projekt
Equinox), framework Spring.− Microsoft: COM, System.Addin w .NET
Framework− open source: architektura SODA w SharpDevelop
i kontenery IoC jak Castle Windsor, Structure Map czy Unity z Patterns & Practices.
− Żadne z powyższych nie jest idealne− MEF jest wyciągnięciem wniosków z tych
wszystkich.
MEF narodzenie− Na CodePlex powstaje projekt MEF
(sierpień 2008): http://mef.codeplex.com/ − MEF staje się częścią .NET 4.0, jako
System.ComponentModel.Composition
using System.ComponentModel.Composition;using System.ComponentModel.Composition.Hosting;
Typowy scenariusz
Aplikacja
RozszerzenieA
RozszerzenieB
Potrzebuję
Menu
Ja mamMenu
Potrzebujępaska
narzędziowego
Ja mampaska
narzędziowy
W erze MEF: Programowanie atrybutami (Attributed Programming Model)
ĆWICZENIEMEF w praktyce …
1, 2, 3, 4 … MEF STARTPodstawy, czyli
Po pierwsze: Część (Composable Part)
− Jest to podstawowy element (fragment, część)
− Jest to fragment aplikacji, która jest pewnego rodzaju układanką
− Podczas działania aplikacji wszystkie jej części są „komponowane” w całość
Part
Po drugie: Kontrakt łączy części (1)
− Poszczególne części nie zależą od siebie nawzajem, zależą natomiast od kontraktu
− Kontrakt (ang. Contract) to pewnego rodzaju pomost pomiędzy różnymi częściami
− To deklaracja, że pewne dwie części mogą ze sobą współpracować
− Każda część (Part) powinna zawierać przynajmniej jedno powiązanie z kontraktem
PartA
PartBContrac
t
PartA
PartB
Po drugie: Kontrakt łączy części (1)
− Kontrakt zwykle oznaczany strzałką
Contract
Po drugie: Kontrakt łączy części (2)
− Import jest kontraktem, który określa, że część go potrzebuje
− Export jest kontraktem, który określa, że część go oferuje
− Każdy Part powinien zawierać przynajmniej jeden import lub export
PartA
PartBImport Export
PartA
Po drugie: Kontrakt łączy części (2)
− Import jest kontraktem, który określa, że część go potrzebuje
− Export jest kontraktem, który określa, że część go oferuje
− Każdy Part powinien zawierać przynajmniej jeden import lub export
PartBImpor
tExpor
t
Part
Po drugie: Kontrakt łączy części (3)
Import
Export
Export Impor
t
Import
Po trzecie: Kontener (Container) (1)
− Dokonuje on kompozycji (wiąże / składa poszczególne części)
− Kontener wykorzystuje informacje o kontraktach by dokonać kompozycji
− Kompozycji dokonuje tak, jak to jest wymagane i możliwe
− Jeżeli czegoś brakuje, to przyjmuje, że nie jest potrzebne i pomija (chyba że oznaczymy, że to jest wymagane i wtedy otrzymamy wyjątek)
Container
PartImpor
t
Export
Export
Import
Import
Composition
Po trzecie: Kontener (Container) (2)
Container
Po czwarte: Katalog
− Katalog jest miejscem skąd pobierane są części do kontenera
− Dostępne katalogi:− AssemblyCatalog− DirectoryCatalog− AgragateCatalog− TypeCatalog− DeploymentCatalog
(Silverlight only)− FilteringCatalog
Opóźniona inicjalizacja (Lazy loading?)
− Wczytywanie wszystkiego na raz może być czasochłonne i zasobochłonne –przykład menu z wielu assembly
− MEF oferuje opóźnioną inicjalizację
− Zamiast konkretnego importu oferuje pewien wrapper (wrapper of the contract) który go opakowuje.
PartB
Part<A
>PartB
Part<A
>
PartA
Lazy<T, TMetadata>
Metadane
− Element związany z lazy loading− Umożliwia dodawanie do części
pewnych znaczników, czy atrybutów− Wartości Metadanych pojawiają się
wcześniej (zanim wczytane będą prawdziwe party
− Metadane mogą być słabo i silnie typowane
Czas życia częściSingleton Factory
Container
Part A
ContainerPart A
Part A
Part A
[PartCreationPolicy(CeationPolicy.NonShared)]
[PartCreationPolicy(CeationPolicy.Shared)]
ĆWICZENIEMEF w praktyce …
MEF podsumowanie (1)− MEF jest rozwiązaniem dla problemu
rozszerzania:− Nie trzeba tworzyć własnej infrastruktury.− Plugin’y mogą być wielo-używalne.
− MEF dostarcza mechanizmy wspomagające IoC/DI – ale nie jest generycznym kontenerem IoC
Assembly aplikacji głównej
Assembly opisu kontraktów
Assembly plugin’ów
[Import] [Export]
Part 1Part
2
Part 3
MEF podsumowanie (2)
− MEF zapewnia standardową rozszerzalność
− MEF oferuje mechanizmy odkrywania i lokalizowania elementów oraz ładowania rozszerzeń.
− MEF pozwala na oznaczanie rozszerzeń pewnymi metadanymi, które później można odczytywać, odpytywać, czy filtrować.
MEF podsumowanie (3)
− Zaleta poza-funkcjonalna:− MEF jest częścią .NET 4.0 !!!
Gdzie szukać informacji
− MEF na Codeplex (dokumentacja, przykłady, kod źródłowy, linki do blogów twórców): http://mef.codeplex.com
− MSDN: Wprowadzenie do Mef: http://msdn.microsoft.com/en-us/library/dd460648.aspx
− MSDN, namespace System.ComponentModel.Composition: http://msdn.microsoft.com/en-us/library/system.componentmodel.composition.aspx
− MSDN Magazine:− http://
msdn.microsoft.com/en-us/magazine/ee291628.aspx − http://
msdn.microsoft.com/en-us/magazine/gg650670.aspx− Kontakt do mnie: [email protected],
http://maciej-progtech.blogspot.com
DZIĘKUJĘ ZA UWAGĘ