Zarządzana struktura rozszerzalności
W tym rozdziale omówimy strukturę zarządzanej rozszerzalności (MEF). MEF może służyć do rozszerzania wtyczek innych firm lub może przynieść korzyści z luźno połączonej architektury podobnej do wtyczki do zwykłych aplikacji.
MEF to biblioteka do tworzenia lekkich, rozszerzalnych aplikacji.
Umożliwia programistom aplikacji odkrywanie i używanie rozszerzeń bez konieczności konfiguracji.
MEF jest integralną częścią .NET Framework 4 i jest dostępny wszędzie tam, gdzie jest używany .NET Framework, co zwiększa elastyczność, łatwość konserwacji i testowalność dużych aplikacji.
Możesz używać MEF w aplikacjach klienckich, niezależnie od tego, czy używają one Windows Forms, WPF lub dowolnej innej technologii, czy w aplikacjach serwerowych, które używają ASP.NET.
MEF został przeniesiony jako Microsoft.Composition do .NET Core, ale częściowo.
Tylko System.Composition jest przenoszony i System.ComponentModel.Compositionnie jest jeszcze dostępny. Oznacza to, że nie mamy katalogów, które mogą ładować typy z zestawów w katalogu.
W tym rozdziale dowiemy się tylko, jak możemy używać MEF w aplikacji .NET Core.
Zrozummy prosty przykład, w którym użyjemy MEF w aplikacji konsoli .NET Core. Utwórzmy teraz nowy projekt konsoli .NET Core.
W lewym okienku wybierz Templates → Visual C# → .NET Core, a następnie w środkowym okienku wybierz pozycję aplikacja konsoli (.NET Core).
Wpisz nazwę projektu w polu Nazwa i kliknij OK.

Po utworzeniu projektu musimy dodać odwołanie do Microsoft.Composition, abyśmy mogli używać MEF. Aby to zrobić, kliknij prawym przyciskiem myszy projekt w Eksploratorze rozwiązań iManage NuGet Packages…
Szukaj Microsoft.Composition i kliknij Install.

Kliknij OK przycisk.

Kliknij I Accept przycisk.

Po zakończeniu instalacji znajdziesz błąd w materiałach referencyjnych.

Otwórzmy project.json plik.
{
"version": "1.0.0-*",
"buildOptions": {
"emitEntryPoint": true
},
"dependencies": {
"Microsoft.Composition": "1.0.30",
"Microsoft.NETCore.App": {
"type": "platform",
"version": "1.0.1"
}
},
"frameworks": {
"netcoreapp1.0": {
"imports": "dnxcore50"
}
}
}
Widać, że plik Microsoft.Composition zależność jest dodana, ale problem polega na tym, że ten pakiet nie jest zgodny z dnxcore50. Więc musimy importowaćportablenet45+win8+wp8+wpa81. Zastąpmy teraz twójproject.json plik z następującym kodem.
{
"version": "1.0.0-*",
"buildOptions": {
"emitEntryPoint": true
},
"dependencies": {
"Microsoft.Composition": "1.0.30",
"Microsoft.NETCore.App": {
"type": "platform",
"version": "1.0.1"
}
},
"frameworks": {
"netcoreapp1.0": {
"imports": "portable-net45+win8+wp8+wpa81"
}
}
}
Zapisz ten plik, a zobaczysz, że błąd został naprawiony.

Jeśli rozwiniesz Referencje, zobaczysz odniesienie do Microsoft.Composition.

Najpierw musimy stworzyć interfejs, który ma zostać wyeksportowany, zaimplementować interfejs i ozdobić klasę atrybutem export. Dodajmy teraz nową klasę.
Wpisz nazwę swojej klasy w polu Nazwa i kliknij Add.

Dodajmy następujący kod w PrintData.cs plik.
using System;
using System.Collections.Generic;
using System.Composition;
using System.Linq;
using System.Threading.Tasks;
namespace MEFDemo {
public interface IPrintData {
void Send(string message);
}
[Export(typeof(IPrintData))]
public class PrintData : IPrintData {
public void Send(string message) {
Console.WriteLine(message);
}
}
}
Jak wspomniano powyżej, katalogi nie są dostępne w przestrzeni nazw Microsoft.Composition. Tak więc załaduje wszystkie typy z zestawu z atrybutem eksportu i dołączy do atrybutu importu, jak pokazano w metodzie Compose w pliku Program.cs.
using System;
using System.Collections.Generic;
using System.Composition;
using System.Composition.Hosting;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
namespace MEFDemo {
public class Program {
public static void Main(string[] args) {
Program p = new Program();
p.Run();
}
public void Run() {
Compose();
PrintData.Send("Hello,this is MEF demo");
}
[Import]
public IPrintData PrintData { get; set; }
private void Compose() {
var assemblies = new[] { typeof(Program).GetTypeInfo().Assembly };
var configuration = new ContainerConfiguration()
.WithAssembly(typeof(Program).GetTypeInfo().Assembly);
using (var container = configuration.CreateContainer()) {
PrintData = container.GetExport<IPrintData>();
}
}
}
}
Uruchommy teraz twoją aplikację, a zobaczysz, że działa, tworząc wystąpienie PrintData klasa.

Aby dowiedzieć się więcej o MEF, odwiedź następujący adres URL https://msdn.microsoft.com/en-us/library/dd460648%28v=vs.110%29.aspx po więcej szczegółów.