前面说完了导入和导出的几种方法,如果大家细心的话会注意到前面我们导出的都是类,那么方法和属性能不能导出呢???答案是肯定的,下面就来说下MEF是如何导出方法和属性的。
还是前面的代码,第二篇中已经提供了下载链接,大家可以下载学习。
首先来说导出属性,因为这个比较简单,和导出类差不多,先来看看代码,主要看我加注释的地方,MusicBook.cs中的代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel.Composition;
namespace MEFDemo
{
[Export("MusicBook")]
public class MusicBook : IBookService
{
//导出私有属性
[Export(typeof(string))]
private string _privateBookName = "Private Music BookName";
//导出公有属性
[Export(typeof(string))]
public string _publicBookName = "Public Music BookName";
public string BookName { get; set; }
}
[Export("MathBook", typeof(IBookService))]
public class MathBook : IBookService
{
public string BookName { get; set; }
public string GetBookName()
{
return "MathBook";
}
}
[Export("HistoryBook", typeof(IBookService))]
public class HistoryBook : IBookService
{
public string BookName { get; set; }
public string GetBookName()
{
return "HistoryBook";
}
}
}
program.cs中的代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
namespace MEFDemo
{
class Program
{
[ImportMany("MathBook")]
public IEnumerable<object> Services { get; set; }
//导入属性,这里不区分public还是private
[ImportMany]
public List<string> InputString { get; set; }
static void Main(string[] args)
{
Program pro = new Program();
pro.Compose();
if (pro.Services != null)
{
foreach (var s in pro.Services)
{
var ss = (IBookService)s;
Console.WriteLine(ss.GetBookName());
}
}
foreach (var str in pro.InputString)
{
Console.WriteLine(str);
}
Console.Read();
}
private void Compose()
{
var catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
CompositionContainer container = new CompositionContainer(catalog);
container.ComposeParts(this);
}
}
}
下面还用foreach遍历输出属性的值,运行即可查看到结果。最后我会附上源码供大家下载,这里就不再截图了。
下面说导出方法吧,同理无论是公有方法还是私有方法都是可以导出的,MusicBook代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel.Composition;
namespace MEFDemo
{
[Export("MusicBook")]
public class MusicBook : IBookService
{
//导出私有属性
[Export(typeof(string))]
private string _privateBookName = "Private Music BookName";
//导出公有属性
[Export(typeof(string))]
public string _publicBookName = "Public Music BookName";
public string BookName { get; set; }
//导出公有方法
[Export(typeof(Func<string>))]
public string GetBookName()
{
return "MusicBook";
}
//导出私有方法
[Export(typeof(Func<int, string>))]
private string GetBookPrice(int price)
{
return "$" + price;
}
}
[Export("MathBook", typeof(IBookService))]
public class MathBook : IBookService
{
public string BookName { get; set; }
public string GetBookName()
{
return "MathBook";
}
}
[Export("HistoryBook", typeof(IBookService))]
public class HistoryBook : IBookService
{
public string BookName { get; set; }
public string GetBookName()
{
return "HistoryBook";
}
}
}
program中的代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
namespace MEFDemo
{
class Program
{
[ImportMany("MathBook")]
public IEnumerable<object> Services { get; set; }
//导入属性,这里不区分public还是private
[ImportMany]
public List<string> InputString { get; set; }
//导入无参数方法
[Import]
public Func<string> methodWithoutPara { get; set; }
//导入有参数方法
[Import]
public Func<int,string> methodWithPara { get; set; }
static void Main(string[] args)
{
Program pro = new Program();
pro.Compose();
if (pro.Services != null)
{
foreach (var s in pro.Services)
{
var ss = (IBookService)s;
Console.WriteLine(ss.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()
{
var catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
CompositionContainer container = new CompositionContainer(catalog);
container.ComposeParts(this);
}
}
}
导入导出方法用到了Func<T>委托,当然没有返回值的话可以用Action<T>委托,关于委托这里就不多说了,大家可以自行百度。