Szukaj…


Uwagi

Jedną z wielkich zalet MEF w porównaniu z innymi technologiami obsługującymi wzorzec inwersji kontroli jest to, że obsługuje rozwiązywanie zależności, które nie są znane w czasie projektowania, bez potrzeby dużej (jeśli w ogóle) konfiguracji.

Wszystkie przykłady wymagają odwołania do zestawu System.ComponentModel.Composition.

Ponadto wszystkie (podstawowe) przykłady wykorzystują je jako przykładowe obiekty biznesowe:

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();
    }
}

Eksportowanie typu (podstawowe)

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();
        }
    }
}

Można to zdefiniować praktycznie wszędzie; liczy się tylko to, że aplikacja wie, gdzie jej szukać (za pośrednictwem tworzonych przez siebie ComposablePartCatalogs).

Importowanie (podstawowe)

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);
            }
        }
    }
}

Jest to typ zależny od IUserProvider , który można zdefiniować w dowolnym miejscu. Podobnie jak w poprzednim przykładzie, wszystko, co się liczy, to to, że aplikacja wie, gdzie szukać pasującego eksportu (za pośrednictwem tworzonych przez siebie ComposablePartCatalogs).

Łączenie (podstawowe)

Zobacz inne (podstawowe) przykłady powyżej.

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();
            }
        }
    }
}

Tak długo, jak coś w ścieżce wyszukiwania zestawu aplikacji ma [Export(typeof(IUserProvider))] , odpowiedni import UserWriter będzie zadowolony i użytkownicy zostaną wydrukowani.

Można używać innych typów katalogów (np. DirectoryCatalog ) zamiast (lub oprócz) ApplicationCatalog , aby szukać w innych miejscach eksportu, które spełniają wymagania importu.



Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow