Ricerca…


Osservazioni

Uno dei grandi vantaggi del MEF rispetto ad altre tecnologie che supportano il pattern di inversione di controllo è che supporta la risoluzione di dipendenze non note in fase di progettazione, senza la necessità di una configurazione (se non nulla).

Tutti gli esempi richiedono un riferimento all'assembly System.ComponentModel.Composition.

Inoltre, tutti gli esempi (di base) li utilizzano come oggetti di business di esempio:

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

Esportare un tipo (base)

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

Questo potrebbe essere definito praticamente ovunque; tutto ciò che conta è che l'applicazione sappia dove cercarlo (tramite ComposablePartCatalogs che crea).

Importazione (base)

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

Questo è un tipo che ha una dipendenza da un IUserProvider , che può essere definito ovunque. Come nell'esempio precedente, tutto ciò che conta è che l'applicazione sappia dove cercare l'esportazione corrispondente (tramite ComposablePartCatalogs che crea).

Connessione (base)

Vedi gli altri esempi (di base) sopra.

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

Finché qualcosa nel percorso di ricerca dell'assembly dell'applicazione ha [Export(typeof(IUserProvider))] , l'importazione corrispondente di UserWriter sarà soddisfatta e gli utenti verranno stampati.

Altri tipi di cataloghi (ad esempio DirectoryCatalog ) possono essere utilizzati al posto di (o in aggiunta a) ApplicationCatalog , per cercare in altri luoghi le esportazioni che soddisfano le importazioni.



Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow