遵循依赖倒置原则,即上层模块不应该依赖于下层模块,而通过抽象来依赖,依赖于抽象,而不是依赖于细节。IOC的实现遵循这个原则。
IOC容器unity把上层模块对下层的依赖存到容器中,在程序中通过依赖注入来使用。
1.安装
2.使用
新建文件,GirlFriend.cs和IGirl.cs
using System; using System.Collections.Generic; using System.Text; namespace app { public class GirlFriend: IGirl { public string Name { get; set; } public int Age { get; set; } public GirlFriend() { this.Name = "对象"; this.Age = 18; } public string Eat() { return "和对象吃饭"; } } }
using System; using System.Collections.Generic; using System.Text; namespace app { public interface IGirl { string Eat(); } }
运行代码
using System; using Unity; namespace app { class Program { static void Main(string[] args) { IUnityContainer container = new UnityContainer(); container.RegisterType<IGirl, GirlFriend>(); var result = container.Resolve<IGirl>(); Console.WriteLine(result.Eat()); } } }
定义容器,注册类型,表示解析到IGril的接口类型时,会自动创建GirlFriend的实例。
如果一个接口有多个实现,可以通过参数的来实现。
创建一个GirlFriend2类。
using System; using System.Collections.Generic; using System.Text; namespace app { public class GirlFriend2: IGirl { public string Name { get; set; } public int Age { get; set; } public GirlFriend2() { this.Name = "对象2号"; this.Age = 18; } public string Eat() { return "和对象2号吃饭"; } } }
运行
using System; using Unity; namespace app { class Program { static void Main(string[] args) { IUnityContainer container = new UnityContainer(); container.RegisterType<IGirl, GirlFriend>("GF"); container.RegisterType<IGirl, GirlFriend2>("GF2"); var result = container.Resolve<IGirl>("GF"); var result2 = container.Resolve<IGirl>("GF2"); Console.WriteLine(result.Eat()); Console.WriteLine(result2.Eat()); } } }
上面的方式还是依赖于底层细节,通过配置文件的方式可以不依赖于底层细节。
创建unity.config文件,该文件需要设置属性为始终复制到输出目录,这样编译后才能生成到debug目录里。
<configuration> <configSections> <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Unity.Configuration"/> </configSections> <unity> <assembly name="app"/> <containers> <container name="gContainer"> <register type="app.IGirl" mapTo="app.GirlFriend" name="GF"/> <register type="app.IGirl" mapTo="app.GirlFriend2" name="GF2"/> </container> </containers> </unity> </configuration>
运行
using Microsoft.Practices.Unity.Configuration; using System; using System.Configuration; using System.IO; using Unity; namespace app { class Program { static void Main(string[] args) { IUnityContainer container = new UnityContainer(); ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap(); fileMap.ExeConfigFilename = Path.Combine(AppDomain.CurrentDomain.BaseDirectory + "unity.config"); Configuration configuration = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None); UnityConfigurationSection section = (UnityConfigurationSection)configuration.GetSection(UnityConfigurationSection.SectionName); section.Configure(container, "gContainer");//写法一:给容器加载在配置文件中name为“gContainer”的<container> //container.LoadConfiguration(section);//写法二:给容器加载在配置文件中没有name的<container> var result = container.Resolve<IGirl>("GF"); var result2 = container.Resolve<IGirl>("GF2"); Console.WriteLine(result.Eat()); Console.WriteLine(result2.Eat()); Console.ReadLine(); } } }