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.