.NET Framework
Managed Extensibility Framework
Suche…
Bemerkungen
Ein großer Vorteil von MEF gegenüber anderen Technologien, die das Control Inversion-of-Control-Verfahren unterstützen, ist die Unterstützung von Abhängigkeiten, die zur Entwurfszeit nicht bekannt sind.
Alle Beispiele erfordern einen Verweis auf die System.ComponentModel.Composition-Assembly.
Alle (Basis-) Beispiele verwenden diese auch als Beispiel für Geschäftsobjekte:
using System.Collections.ObjectModel;
namespace Demo
{
public sealed class User
{
public User(int id, string name)
{
this.Id = id;
this.Name = name;
}
public int Id { get; }
public string Name { get; }
public override string ToString() => $"User[Id: {this.Id}, Name={this.Name}]";
}
public interface IUserProvider
{
ReadOnlyCollection<User> GetAllUsers();
}
}
Typ exportieren (Basic)
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel.Composition;
namespace Demo
{
[Export(typeof(IUserProvider))]
public sealed class UserProvider : IUserProvider
{
public ReadOnlyCollection<User> GetAllUsers()
{
return new List<User>
{
new User(0, "admin"),
new User(1, "Dennis"),
new User(2, "Samantha"),
}.AsReadOnly();
}
}
}
Dies könnte praktisch überall definiert werden. Wichtig ist nur, dass die Anwendung weiß, wo sie suchen soll (über die erstellten ComposablePartCatalogs).
Importieren (Basic)
using System;
using System.ComponentModel.Composition;
namespace Demo
{
public sealed class UserWriter
{
[Import(typeof(IUserProvider))]
private IUserProvider userProvider;
public void PrintAllUsers()
{
foreach (User user in this.userProvider.GetAllUsers())
{
Console.WriteLine(user);
}
}
}
}
Dies ist ein Typ, der von einem IUserProvider
, der an einer IUserProvider
Stelle definiert werden kann. Wie im vorherigen Beispiel ist es nur wichtig, dass die Anwendung weiß, wo nach dem entsprechenden Export gesucht werden soll (über die erstellten ComposablePartCatalogs).
Anschließen (Basic)
Siehe die anderen (grundlegenden) Beispiele oben.
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
namespace Demo
{
public static class Program
{
public static void Main()
{
using (var catalog = new ApplicationCatalog())
using (var exportProvider = new CatalogExportProvider(catalog))
using (var container = new CompositionContainer(exportProvider))
{
exportProvider.SourceProvider = container;
UserWriter writer = new UserWriter();
// at this point, writer's userProvider field is null
container.ComposeParts(writer);
// now, it should be non-null (or an exception will be thrown).
writer.PrintAllUsers();
}
}
}
}
Solange etwas im Assembly-Suchpfad der Anwendung [Export(typeof(IUserProvider))]
, UserWriter
der entsprechende Import von UserWriter
erfüllt und die Benutzer werden gedruckt.
Andere Arten von Katalogen (z. B. DirectoryCatalog
) können anstelle von (oder zusätzlich zu) ApplicationCatalog
, um an anderen Stellen nach Exporten zu suchen, die die Importe erfüllen.