IOC框架:Unity
Unity 是一个轻量级、可扩展的依赖注入容器,支持构造函数、属性和方法调用注入。
在进行项目之前通过Nuget安装Unity
简单的例子
定义一个接口
namespace UnityTest { //动物 public interface IAnimal { void Eat(); } }
两个派生类
namespace UnityTest { //狗 public class Dog : IAnimal { public void Eat() { Console.WriteLine("正在吃狗粮"); } } //猫 public class Cat : IAnimal { public void Eat() { Console.WriteLine("正在吃猫粮"); } } }
namespace UnityTest { class Program { static void Main(string[] args) { //创建一个容器 IUnityContainer unityContainer = new UnityContainer(); //注册依赖对象 ,别名区分 unityContainer.RegisterType<IAnimal, Dog>("dog"); unityContainer.RegisterType<IAnimal, Cat>("cat"); IAnimal dog = unityContainer.Resolve<IAnimal>("dog"); IAnimal cat = unityContainer.Resolve<IAnimal>("cat"); dog.Eat(); cat.Eat(); Console.Read(); } } }
结果
构造函数注入
新加一个接口:
//午餐 public interface ILunch { void Doing(); }
派生类
public class Lunch : ILunch { private IAnimal animal; public Lunch(IAnimal aa) { this.animal = aa; } public void Doing() { animal.Eat(); } }
namespace UnityTest { class Program { static void Main(string[] args) { //创建一个容器 IUnityContainer unityContainer = new UnityContainer(); //注册依赖对象 unityContainer.RegisterType<IAnimal, Dog>(); ILunch l = unityContainer.Resolve<Lunch>();
l.Doing();
Console.Read(); } } }
结果:
PS:
IoC容器会智能地选择选择和调用适合的构造函数以创建依赖的对象(自动使用参数最多的构造函数来进行创建对象)。假如在这个类中有多个构造函数时,而我们要指定其中一个作为Unity进行创建对象则必需用到[InjectionConstructor]
如果被选择的构造函数具有相应的参数,IoC容器在调用构造函数之前解析注册的依赖关系并自行获得相应参数对象。
属性注入
通过 set 对对象进行设值,只需要在调用对象的上面加上 [Dependency] 标记即可。当依赖对象被容器初始化以后,会自动对该对象设值。
public class Lunch : ILunch { [Dependency] public IAnimal animal { get; set; } public void Doing() { animal.Eat(); } }
方法注入
方法注入和构造注入差不多,只不过把构造函数变成了一个普通的方法,在方法前面加 [InjectionMethod] 属性。
public class Lunch : ILunch { private IAnimal Dog; [InjectionMethod] public init(IAnimal aa) { this.Dog = aa; } public void Doing() { Dog.Eat(); } }
配置文件形式注册
<?xml version="1.0" encoding="utf-8" ?> <configuration> <configSections> <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Unity.Configuration" /> </configSections> <unity> <alias alias="IAnimal" type="UnityTest.IAnimal, UnityTest"></alias> <alias alias="ILunch" type="UnityTest.ILunch, UnityTest"></alias> <containers> <container name="MyContainer"> <register name="D" type="IAnimal" mapTo="UnityTest.Dog,UnityTest"></register> <register name="C" type="IAnimal" mapTo="UnityTest.Cat, UnityTest"></register> </container> </containers> </unity> <!--startup必须放在<configSections>节点下面,否则报错--> <startup> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" /> </startup> </configuration>
class Program { static void Main(string[] args) { UnityContainer container = new UnityContainer(); UnityConfigurationSection config = (UnityConfigurationSection)ConfigurationManager.GetSection(UnityConfigurationSection.SectionName); config.Configure(container, "MyContainer");
//若是只有一个基类,可以没有别名,本文例子,该接口有多个基类所以要别名 IAnimal aa = container.Resolve<IAnimal>("D"); aa.Eat(); Console.Read(); } }