[Solution] DI原理解析及Castle、Unity框架使用
本节目录
DI介绍
控制反转(Inversion of Control,英文缩写为IoC)是一个重要的面向对象编程的法则来削减计算机程序的耦合问题.
依赖注入(Dependency Injection,英文缩写为DI)是一种设计模式.
其实本质都是指同一件事,强调的内容不一样.IoC强调容器的作用,DI强调注入的作用.
通常IoC和DI可以理解为一个意思,只是指的对象不同.
DI基本原理
DI本质上是通过容器来反射创建实例.
1个简单的类
class Person { public void Say() { Console.WriteLine("Person's say method is Called"); } }
反射代码(className:类的全限定名)
private static object CreateInstance(Assembly assembly, string className) { var type = assembly.GetType(className); return type != null ? Activator.CreateInstance(type) : null; }
执行(XX为命名空间)
static void Main(string[] args) { var obj = CreateInstance(Assembly.GetExecutingAssembly(), "XX.Person"); var person = obj as Person; if (person != null) { person.Say(); } Console.ReadKey(); }
在上面能看到1个问题,一般情况下.既然使用DI,就不知道具体的注入对象.所以强调面向接口编程.
所以实际上一般先定义接口,再通过DI容器创建对象.
interface IPerson { void Say(); } class Person : IPerson { public void Say() { Console.WriteLine("Person's say method is Called"); } }
执行
static void Main(string[] args) { var obj = CreateInstance(Assembly.GetExecutingAssembly(), "Demo.Person"); var person = obj as IPerson; if (person != null) { person.Say(); } Console.ReadKey(); }
DI框架
DI框架流行的有Castle Windsor,Unity...(Autofac Spring.Net已经聊过,不再演示)
在DI框架中,一般需要将对象注册到容器中,然后从容器解析出来.
Castle
Install-Package Castle.Windsor
待注入类
interface ITransient { } interface IPerson { void Say(); } class Person : IPerson, ITransient { public void Say() { Console.WriteLine("Person's say method is Called"); } }
注册解析方式一
static void Main(string[] args) { using (var container = new WindsorContainer()) { container.Register(Component.For<Person, IPerson>()); var person = container.Resolve<IPerson>(); person.Say(); } Console.ReadKey(); }
注册解析方式二
public class AssmInstaller : IWindsorInstaller { public void Install(IWindsorContainer container, IConfigurationStore store) { container.Register(Classes.FromThisAssembly() //选择Assembly .IncludeNonPublicTypes() //约束Type .BasedOn<ITransient>() //约束Type .WithService.DefaultInterfaces() //匹配类型 .LifestyleTransient()); //注册生命周期 } }
static void Main(string[] args) { using (var container = new WindsorContainer()) { container.Install(new AssmInstaller()); var person = container.Resolve<IPerson>(); person.Say(); } Console.ReadKey(); }
构造函数注入
class Task : ITransient { public IPerson Person { get; set; } public Task(IPerson person) { Person = person; Person.Say(); } }
static void Main(string[] args) { using (var container = new WindsorContainer()) { container.Install(new AssmInstaller()); container.Resolve<Task>(); } Console.ReadKey(); }
属性注入
class Task : ITransient { public IPerson Person { get; set; } public Task() { } public void Say() { Person.Say(); } }
static void Main(string[] args) { using (var container = new WindsorContainer()) { container.Install(new AssmInstaller()); container.Resolve<Task>().Say(); } Console.ReadKey(); }
MVC集成
Install-Package Castle.Windsor.Mvc
Application_Start注册
protected void Application_Start() { RouteConfig.RegisterRoutes(RouteTable.Routes); var container = new WindsorContainer() .Install(FromAssembly.This()); var controllerFactory = new WindsorControllerFactory(container.Kernel); ControllerBuilder.Current.SetControllerFactory(controllerFactory); }
Installer注册
public class AssmInstaller : IWindsorInstaller { public void Install(IWindsorContainer container, IConfigurationStore store) { container.Register(Classes.FromThisAssembly() .IncludeNonPublicTypes() .BasedOn<ITransient>() .WithService.DefaultInterfaces() .LifestyleTransient()); container.Register(Classes.FromThisAssembly() .BasedOn<Controller>() .LifestyleTransient() ); } }
这样Castle Windsor就能接管解析Controller了.
Unity
Install-Package Unity
待注入类
public interface IPerson { void Say(); } public class Person : IPerson { public void Say() { Console.WriteLine("Person's say method is Called"); } }
注册解析一
static void Main(string[] args) { using (var container = new UnityContainer()) { container.RegisterType<IPerson, Person>(new TransientLifetimeManager()); var person = container.Resolve<IPerson>(); person.Say(); } Console.ReadKey(); }
注册解析二
static void Main(string[] args) { using (var container = new UnityContainer()) { container.RegisterInstance<IPerson>(new Person()); var person = container.Resolve<IPerson>(); person.Say(); } Console.ReadKey(); }
构造函数注入
class Task : ITask { public IPerson Person { get; set; } public Task(IPerson person) { Person = person; Person.Say(); } } public interface ITask { }
static void Main(string[] args) { using (var container = new UnityContainer()) { container.RegisterInstance<IPerson>(new Person()); container.RegisterType<ITask, Task>(); container.Resolve<ITask>(); } Console.ReadKey(); }
属性注入
class Task : ITask { [Dependency] public IPerson Person { get; set; } public Task(IPerson person) { Person = person; } public void Say() { Person.Say(); } }
static void Main(string[] args) { using (var container = new UnityContainer()) { container.RegisterInstance<IPerson>(new Person()); container.RegisterType<ITask, Task>(); var task = container.Resolve<ITask>(); task.Say(); } Console.ReadKey(); }
MVC集成
Install-Package Unity.Mvc
Application_Start注册
protected void Application_Start() { RouteConfig.RegisterRoutes(RouteTable.Routes); var container = new UnityContainer(); container.RegisterType<IPerson, Person>(); DependencyResolver.SetResolver(new UnityDependencyResolver(container)); }
这样Unity就接管了Controller的创建
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。 如果觉得还有帮助的话,可以点一下右下角的【推荐】,希望能够持续的为大家带来好的技术文章!想跟我一起进步么?那就【关注】我吧。