[C# Advanced Series] [MEF Framework (3)]

C# Advanced Series

Chapter 3 [C# Advanced Series] [MEF Framework (3)]
Chapter 2 [C# Advanced Series] [MEF Framework (2)]
Chapter 1 [C# Advanced Series] [MEF Framework (1)]



Preface

In (1), we have given a basic introduction to MEF. The previous ones introduced how to export classes. Here are some supplements on how MEF exports methods and properties.


1. Export attributes

Just look at the code example below, it is no different from the exported class.

namespace MEF_P1
{
    
    
    public interface IBookService
    {
    
    
        string GetBookName();
    }
    [Export("ContractName_MathBook")]
    public class MathBook : IBookService
    {
    
    
        //导出私有属性
        [Export(typeof(string))]
        private string _privateBookName = "Private MathBook BookName";
        //导出公有属性
        [Export(typeof(string))]
        public string _publicBookName = "Public MathBook BookName";
        public string GetBookName()
        {
    
    
            return "MathBook";
        }
    }
    [Export("ContractName_ChineseBook")]
    public class ChineseBook : IBookService
    {
    
    
        public string GetBookName()
        {
    
    
            return "ChineseBook";
        }
    }
    class Program
    {
    
    
        //导入属性,这里不区分public还是private
        [ImportMany]
        public List<string> InputString {
    
     get; set; }
        public object Services_MathBook {
    
     get; set; }
        public object Services_ChineseBook {
    
     get; set; }
        static void Main(string[] args)
        {
    
    
            Program pro = new Program();
            pro.Compose();
            if (pro.Services_MathBook != null)
            {
    
    
                Console.WriteLine(((IBookService)pro.Services_MathBook).GetBookName());
            }
            if (pro.Services_ChineseBook != null)
            {
    
    
                Console.WriteLine(((IBookService)pro.Services_ChineseBook).GetBookName());
            }
            foreach (var str in pro.InputString)
            {
    
    
                Console.WriteLine(str);
            }
            Console.Read();
        }
        private void Compose()
        {
    
    
            //创建一个程序集目录,用于从一个程序集获取所有的组件定义
            AssemblyCatalog catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
            //创建容器
            CompositionContainer container = new CompositionContainer(catalog);
            //组合部件:如果该类有Import,就会自动去寻找Export
            container.ComposeParts(this);
            //直接通过契约名获取Export
            Services_MathBook = container.GetExportedValue<object>("ContractName_MathBook");
            Services_ChineseBook = container.GetExportedValue<object>("ContractName_ChineseBook");
        }
    }
}

2. Export method

The exported method is special, and also distinguishes between those with parameters and those without parameters. The usage is somewhat similar to that of delegation. If there
is a return value, use the Func delegate, and if there is no return value, use the Action delegate.

namespace MEF_P1
{
    
    
    public interface IBookService
    {
    
    
        string GetBookName();
    }
    [Export("ContractName_MathBook")]
    public class MathBook : IBookService
    {
    
    
        //导出私有属性
        [Export(typeof(string))]
        private string _privateBookName = "Private MathBook BookName";
        //导出公有属性
        [Export(typeof(string))]
        public string _publicBookName = "Public MathBook BookName";
        //导出私有无参方法
        [Export(typeof(Func<string>))]
        public string GetBookName()
        {
    
    
            return "MathBook";
        }
        //导出公有带参方法
        [Export(typeof(Func<int, string>))]
        public string GetBookPrice(int price)
        {
    
    
            return "¥" + price;
        }
    }
    [Export("ContractName_ChineseBook")]
    public class ChineseBook : IBookService
    {
    
    
        public string GetBookName()
        {
    
    
            return "ChineseBook";
        }
    }
    class Program
    {
    
    
        //导入属性,这里不区分public还是private
        [ImportMany]
        public List<string> InputString {
    
     get; set; }
        //导入无参数方法
        [Import]
        public Func<string> methodWithoutPara {
    
     get; set; }
        //导入有参数方法
        [Import]
        public Func<int, string> methodWithPara {
    
     get; set; }
        public object Services_MathBook {
    
     get; set; }
        public object Services_ChineseBook {
    
     get; set; }
        static void Main(string[] args)
        {
    
    
            Program pro = new Program();
            pro.Compose();
            if (pro.Services_MathBook != null)
            {
    
    
                Console.WriteLine(((IBookService)pro.Services_MathBook).GetBookName());
            }
            if (pro.Services_ChineseBook != null)
            {
    
    
                Console.WriteLine(((IBookService)pro.Services_ChineseBook).GetBookName());
            }
            foreach (var str in pro.InputString)
            {
    
    
                Console.WriteLine(str);
            }
            //调用无参数方法
            if (pro.methodWithoutPara != null)
            {
    
    
                Console.WriteLine(pro.methodWithoutPara());
            }
            //调用有参数方法
            if (pro.methodWithPara != null)
            {
    
    
                Console.WriteLine(pro.methodWithPara(3000));
            }
            Console.Read();
        }
        private void Compose()
        {
    
    
            //创建一个程序集目录,用于从一个程序集获取所有的组件定义
            AssemblyCatalog catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
            //创建容器
            CompositionContainer container = new CompositionContainer(catalog);
            //组合部件:如果该类有Import,就会自动去寻找Export
            container.ComposeParts(this);
            //直接通过契约名获取Export
            Services_MathBook = container.GetExportedValue<object>("ContractName_MathBook");
            Services_ChineseBook = container.GetExportedValue<object>("ContractName_ChineseBook");
        }
    }
}

Summarize

Dependency Inversion Principle: High-level templates should not depend on low-level templates, both should depend on abstractions, and abstractions should not depend on details.

Guess you like

Origin blog.csdn.net/Aflashstar/article/details/129098584