[Solution] DI原理解析及Castle、Unity框架使用
本节目录
DI介绍
控制反转(Inversion of Control,英文缩写为IoC)是一个重要的面向对象编程的法则来削减计算机程序的耦合问题.
依赖注入(Dependency Injection,英文缩写为DI)是一种设计模式.
其实本质都是指同一件事,强调的内容不一样.IoC强调容器的作用,DI强调注入的作用.
通常IoC和DI可以理解为一个意思,只是指的对象不同.
DI基本原理
DI本质上是通过容器来反射创建实例.
1个简单的类
1 2 3 4 5 6 7 | class Person { public void Say() { Console.WriteLine( "Person's say method is Called" ); } } |
反射代码(className:类的全限定名)
1 2 3 4 5 | private static object CreateInstance(Assembly assembly, string className) { var type = assembly.GetType(className); return type != null ? Activator.CreateInstance(type) : null ; } |
执行(XX为命名空间)
1 2 3 4 5 6 7 8 9 10 | 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容器创建对象.
1 2 3 4 5 6 7 8 9 10 11 | interface IPerson { void Say(); } class Person : IPerson { public void Say() { Console.WriteLine( "Person's say method is Called" ); } } |
执行
1 2 3 4 5 6 7 8 9 10 | 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
待注入类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | interface ITransient { } interface IPerson { void Say(); } class Person : IPerson, ITransient { public void Say() { Console.WriteLine( "Person's say method is Called" ); } } |
注册解析方式一
1 2 3 4 5 6 7 8 9 10 | 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(); } |
注册解析方式二
1 2 3 4 5 6 7 8 9 10 11 | public class AssmInstaller : IWindsorInstaller { public void Install(IWindsorContainer container, IConfigurationStore store) { container.Register(Classes.FromThisAssembly() //选择Assembly .IncludeNonPublicTypes() //约束Type .BasedOn<ITransient>() //约束Type .WithService.DefaultInterfaces() //匹配类型 .LifestyleTransient()); //注册生命周期 } } |
1 2 3 4 5 6 7 8 9 10 | static void Main( string [] args) { using ( var container = new WindsorContainer()) { container.Install( new AssmInstaller()); var person = container.Resolve<IPerson>(); person.Say(); } Console.ReadKey(); } |
构造函数注入
1 2 3 4 5 6 7 8 9 | class Task : ITransient { public IPerson Person { get ; set ; } public Task(IPerson person) { Person = person; Person.Say(); } } |
1 2 3 4 5 6 7 8 9 | static void Main( string [] args) { using ( var container = new WindsorContainer()) { container.Install( new AssmInstaller()); container.Resolve<Task>(); } Console.ReadKey(); } |
属性注入
1 2 3 4 5 6 7 8 9 10 11 | class Task : ITransient { public IPerson Person { get ; set ; } public Task() { } public void Say() { Person.Say(); } } |
1 2 3 4 5 6 7 8 9 | 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注册
1 2 3 4 5 6 7 8 | 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注册
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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
待注入类
1 2 3 4 5 6 7 8 9 10 11 | public interface IPerson { void Say(); } public class Person : IPerson { public void Say() { Console.WriteLine( "Person's say method is Called" ); } } |
注册解析一
1 2 3 4 5 6 7 8 9 10 | 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(); } |
注册解析二
1 2 3 4 5 6 7 8 9 10 | static void Main( string [] args) { using ( var container = new UnityContainer()) { container.RegisterInstance<IPerson>( new Person()); var person = container.Resolve<IPerson>(); person.Say(); } Console.ReadKey(); } |
构造函数注入
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | class Task : ITask { public IPerson Person { get ; set ; } public Task(IPerson person) { Person = person; Person.Say(); } } public interface ITask { } |
1 2 3 4 5 6 7 8 9 10 | static void Main( string [] args) { using ( var container = new UnityContainer()) { container.RegisterInstance<IPerson>( new Person()); container.RegisterType<ITask, Task>(); container.Resolve<ITask>(); } Console.ReadKey(); } |
属性注入
1 2 3 4 5 6 7 8 9 10 11 12 13 | class Task : ITask { [Dependency] public IPerson Person { get ; set ; } public Task(IPerson person) { Person = person; } public void Say() { Person.Say(); } } |
1 2 3 4 5 6 7 8 9 10 11 | 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注册
1 2 3 4 5 6 7 | protected void Application_Start() { RouteConfig.RegisterRoutes(RouteTable.Routes); var container = new UnityContainer(); container.RegisterType<IPerson, Person>(); DependencyResolver.SetResolver( new UnityDependencyResolver(container)); } |
这样Unity就接管了Controller的创建
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。 如果觉得还有帮助的话,可以点一下右下角的【推荐】,希望能够持续的为大家带来好的技术文章!想跟我一起进步么?那就【关注】我吧。
分类:
[07]Solution
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义