IOC能做什么
IoC 不是一种技术,只是一种思想,一个重要的面向对象编程的法则,它能指导我们如何设计出松耦合、更优良的程序。
控制反转:
将控制权移交给第三方容器 new 操作
依赖注入:
在程序的运行过程中 动态的给某个对象 注入他所需要的 实例
例子:模拟一个用户购买了一个音乐播放器
用户类
public class User { //初始化一个音乐播放器 public MusicPlayer Playe = new MusicPlayer(); public void Play() { Playe.Play(); } }
/// <summary> /// 音乐播放器 /// </summary> public class MusicPlayer { public void Play() { Console.WriteLine("音乐播放器"); } }
控制台
class Program { static void Main(string[] args) { var u =new User(); u.Play(); Console.ReadKey(); } }
输出
需求改变
用户需要将音乐播放器改为视频播放器
1.新建一个视频播放器提供商程序集 以及视频播放器类
/// <summary> /// 视频播放器 /// </summary> public class VideoPlayer { public void Play() { Console.WriteLine("视频播放器"); } }
2.删除上层的音乐播放器的引用 并引用视频播放器。将用户的new 音乐播放器 改为new视频播放器
public class User { public VideoPlayer Playe = new VideoPlayer(); public void Play() { Playe.Play(); } }
执行输出
问题
下层改变 影响上层
修改
遵循设计模式 依赖导致原则
即上层不直接依赖下层。他们都只依赖下层的抽象(抽象类 或接口)
这个时候我们为播放器抽象一个契约
/// <summary> /// 播放器契约类 /// </summary> public interface IPlayer { void Play(); }
并在音乐播放器 和视频播放器 实现播放契约
/// <summary> /// 视频播放器 /// </summary> public class VideoPlayer : IPlayer { public void Play() { Console.WriteLine("视频播放器"); } }
/// <summary> /// 音乐播放器 /// </summary> public class MusicPlayer:IPlayer { public void Play() { Console.WriteLine("音乐播放器"); } }
使用MEF IOC 实现上层与下层的完全解耦
MEF的特点
1. .net4.0新增 在System.ComponentModel.Composition 程序集 不需要引用第三方类库
2. 0配置:MEF是不需要使用配置文件或代码对接口与实现进行一一配对的,只需要简单的使用几个Attribute特性,就能自动完成源与目标的配对工
3. 自动化:系统初始化时自动遍历程序目录或指定文件夹下的dll,根据程序集中接口与类的特定Attribute特性进行自动配对。
开始使用
1、ui层引用契约接口层 而不引用音乐播放器提供商 和 视频播放器提供商
2.引用MEF所需程序集System.ComponentModel.Composition
将托管于IOC容器的类打上Export 并标记他对应的接口
/// <summary> /// 视频播放器 /// </summary> [Export(typeof(IPlayer))] public class VideoPlayer : IPlayer { public void Play() { Console.WriteLine("视频播放器"); } }
/// <summary> /// 音乐播放器 /// </summary> [Export(typeof(IPlayer))] public class MusicPlayer:IPlayer { public void Play() { Console.WriteLine("音乐播放器"); } }
控制台使用
class Program { public static CompositionContainer _container; static void Main(string[] args) { AggregateCatalog catalog = new AggregateCatalog(); //将当前程序集 打了特性Export的类 导入容器 catalog.Catalogs.Add(new AssemblyCatalog(Assembly.GetExecutingAssembly())); //将运行目录下的MusicPlayerManufacturer 打了特性Export的类导入容器 catalog.Catalogs.Add(new AssemblyCatalog(Assembly.Load("MusicPlayerManufacturer"))); _container = new CompositionContainer(catalog); //在容器中获得User类的对象 var u = _container.GetExportedValue<User>(); u.Play(); Console.ReadKey(); } }
当我们需要使用视频播放器 只需要将视频播放器的接口复制到bin目录 MEF注入 改为 视频播放器接口就行了
还没写完。。。有空再写