MEF 根据配置注入Service

  有这样的场景 :

  现在一个接口有很多种实现类,需要根据配置,来确定确定调用哪个具体的实现类。这样使得软件扩展性大大提高

  在MEF可以通过ExportMetadata 来实现这样的效果。

  1.现在我们建个接口:

namespace ConsoleApplication1.Interface
{
    public interface IMIService
    {
        void SignIn();
    }
}

2.新建一个meta类

namespace ConsoleApplication1.Metadata
{
    public interface PlaceMetadata
    {
        string Place { get; }
    }
}

3.有两个实现类

namespace ConsoleApplication1.Impl
{
    //[Export("hangzhou", typeof(IMIService))]
    [Export(typeof(IMIService))]
    [ExportMetadata("Place", "hangzhou")]
    public class HZMIService : IMIService
    {
        public void SignIn()
        {
            Console.WriteLine("HZ SignIn");
        }
    }
}
namespace ConsoleApplication1.Impl
{
    //[Export("shanghai", typeof(IMIService))]
    [Export(typeof(IMIService))]
    [ExportMetadata("Place", "shanghai")]
    public class SHMIService : IMIService
    {
        public void SignIn()
        {
            Console.WriteLine("SH MI");
        }
    }
}

4.在程序中根据不同的配置来调用不同的实现类

namespace ConsoleApplication1
{
    class Program
    {
        //const string place = "hangzhou";


        //[Import(place)]
        //public IMIService MIService { set; get; }

        [ImportMany]
        IEnumerable<Lazy<IMIService, PlaceMetadata>> DoList { set; get; }

        public IMIService MIService { set; get; }

        static void Main(string[] args)
        {
            Program program = new Program();
            program.Compose();

            var service = program.DoList.Where(x => x.Metadata.Place == "hangzhou").FirstOrDefault();
            program.MIService = service.Value;
            program.MIService.SignIn();
        }

        void Compose()
        {
            var catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
            CompositionContainer container = new CompositionContainer(catalog);
            container.ComposeParts(this);
        }
    }
}

原文地址:https://www.cnblogs.com/nele/p/5700530.html