MEF中应用IOC
IOC介绍:
Ioc就是控制反转的意思。从编程角度讲就是它就是一个容器,用来避免耦合。我们事先把ABC三个对象装进去,然后突然有个D要来使用C这个对象,D就不用直接去获取C这个对象,而是由其它人主动把C给送来。.net中可用的IOC容器非常多,如 CastleWindsor,Unity,Autofac,ObjectBuilder,StructureMap,Spring.Net等,这些第三方工具各不相同,但功能大体都相同,大都需要事先对接口与实现进行配对(通过代码或配置文件),然后由系统自动或手动来通过接口来获得相应实现类的实例,对象实例化的工作由IOC容器自动完成。
MEF介绍:
MEF(Managed Extensibility Framework)是.NET Framework 4.0一个重要的库
MEF的核心是可组合组件ComposablePart,它由ComposablePartDefintion来描述和创建。每一个可组合组件通过定义 ExportDefintion向其它组件提供功能,通过ImportDefinition引用其它组件的功能,通过Metadata来描述组件自身的信 息。在创建一个ComposablePart组件后,通过在组件目录(ComposableCatalog)搜索需要的功能实现组件组合。
MEF优势:
在 System.ComponentModel.Composition.dll 程序集中,直接引用即可使用,不用安装第三方组件。不需要配置,只需要几个特性,使用之方便,容易上手。
使用的目的:
采用面向接口编程,就不能依赖于具体的实现,层与层之间通过接口隔离。。
少废话,直接上代码:
首先做准备工作 ,实现接口IDependencyResolver,完成MEF依赖关系解析。
public class MefDependencySolver : System.Web.Mvc.IDependencyResolver
{
private readonly ComposablePartCatalog _catalog;
private const string HttpContextKey = "MefContainerKey";
public MefDependencySolver(ComposablePartCatalog catalog)
{
_catalog = catalog;
}
public CompositionContainer Container
{
get
{
if (!HttpContext.Current.Items.Contains(HttpContextKey))
{
HttpContext.Current.Items.Add(HttpContextKey, new CompositionContainer(_catalog));
}
CompositionContainer container = (CompositionContainer)HttpContext.Current.Items[HttpContextKey];
HttpContext.Current.Application["Container"] = container;
return container;
}
}
public object GetService(Type serviceType)
{
string contractName = AttributedModelServices.GetContractName(serviceType);
return Container.GetExportedValueOrDefault<object>(contractName);
}
public IEnumerable<object> GetServices(Type serviceType)
{
return Container.GetExportedValues<object>(serviceType.FullName);
}
}
在Global.asax.cs中进行初始化MEF容器:
//初始化MEF依赖注入容器
DirectoryCatalog catalog = new DirectoryCatalog(AppDomain.CurrentDomain.SetupInformation.PrivateBinPath);//创建一个程序集目录,用于从一个程序集获取所有的组件定义
MefDependencySolver solver = new MefDependencySolver(catalog);
DependencyResolver.SetResolver(solver); //注册这个解析类
创建一个IUserService接口和一个UserService实现:
public interface IUserService
{
string GetUserName(string name);
string GetUserInfo(string name, int age, string sex);
}
//实现上面接口
[Export(typeof(IUserService))] //注意这个是必须添加的是MEF导出的特性
public class UserService : IUserService
{
/// <summary>
/// 得到用户名
/// </summary>
/// <returns></returns>
public string GetUserName(string name)
{
return name;
}
/// <summary>
/// 得到用户信息
/// </summary>
/// <returns></returns>
public string GetUserInfo(string name,int age,string sex)
{
return string.Format("用户信息分别是:姓名:{0},年龄:{1},性别:{2}",name,age,sex);
}
}
代码中使用,比喻得到一个用户的姓名:
[Export]
public class HomeController : Controller
{
[Import] //拿到容器里的一个对象
private IUserService _userService { get; set; }
public ActionResult Index()
{
string name = _userService.GetUserName("吴尚鸿");
return View();
}
}
注:这样我们的目的就达到了,完全依赖接口,不依赖实现。那有同学会问。
通过构造函数来实现:
[Export]
public class HomeController : Controller
{
private IUserService _userService { get; set; }
[ImportingConstructor]
public HomeController(IUserService userService)
{
_userService = userService;
}
public ActionResult Index()
{
string name = _userService.GetUserName("吴尚鸿");
return View();
}
}

浙公网安备 33010602011771号