[Solution] 使用Autofac在MVC、Web API、WCF中实现IOC
本来想聊一下面试过程的,1个星期面了6家,4家当场给offer,2家技术通过(1家没下文,1家复试).从中也学习到一些东西,先还是继续Coding吧.
官网:http://autofac.org/
下载:Install-Package Autofac -Version 3.5.2
Autofac是轻量级的开源IOC容器,传说是速度最快的一个,同类的框架还有用过Castle Windsor、StructureMap、Unity、Spring.Net等.
本节目录
1.建立项目
CA:一个控制台项目,引用Nuget Autofac包.
2.建立一个依赖外部的类
1 2 3 4 5 6 7 | public class Test { public Test( string str) { Console.WriteLine( "hello " + str); } } |
3.根据参数名直接注入
1 2 3 4 5 6 7 8 9 10 11 | static void Main( string [] args) {<br> //创建容器工厂 var builder = new ContainerBuilder(); //注册Test类型到工厂中 builder.RegisterType<Test>();<br> //通过工厂创建容器 using ( var container = builder.Build()) {<br> //解析Test并返回Test实例 container.Resolve<Test>( new NamedParameter( "str" , "world" )); } Console.ReadKey(); } |
过程:首先需要创建容器工厂,然后将各种类型注册到工厂中,再创建容器,通过容器实例化对象.
添加1个构造函数
1 2 3 4 | public Test(ISay say) { Console.WriteLine( "say:" + say.Get()); } |
接口及其实现
1 2 3 4 5 6 7 8 9 10 11 12 | public class Say : ISay { public string Get() { return "hello world" ; } } public interface ISay { string Get(); } |
注入实现(Autofac会自动装配)
1 2 3 4 5 6 7 8 9 10 11 12 | static void Main( string [] args) { var builder = new ContainerBuilder(); builder.RegisterType<Test>(); builder.RegisterType<Say>().As<ISay>(); using ( var container = builder.Build()) { container.Resolve<Test>(); } Console.ReadKey(); } |
略作修改
1 2 3 4 | public Test(Say say) //将接口改为指定具体实现类 { Console.WriteLine( "say:" + say.Get()); } |
此时运行代码会报错,因为在容器中我们只注册了ISay接口.改为As<Say>或以下方式
1 | builder.RegisterType<Say>().As<ISay>().AsSelf(); |
对象生命周期
注册到工厂的类型默认都调用InstancePerDependency方法.实现每个依赖都创建1个新实例
单例模式:
1 | builder.RegisterType<Test>().SingleInstance(); |
需要引用Nuget Autofac.Configuration包
注册类型代码
1 | builder.RegisterModule( new ConfigurationSettingsReader( "autofac" )); |
App.config
1 2 3 4 5 6 7 8 9 | <configSections> <section name= "autofac" type= "Autofac.Configuration.SectionHandler, Autofac.Configuration" /> </configSections> <autofac defaultAssembly= "CA" > <components> <component type= "CA.Say, CA" service= "CA.ISay" /> <component type= "CA.Say, CA" service= "CA.Say" /> </components> </autofac> |
service相当于As<T>中的T
1.Install-Package Autofac.Mvc5
2.Application_Start事件添加此方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | protected void Application_Start( object sender, EventArgs e) { #region 1.MVC Autofac注入 var builder = new ContainerBuilder(); //类名.EndsWith("Controller") builder.RegisterControllers(Assembly.GetExecutingAssembly()); //这样既支持接口 又支持自己的类型 builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly()) .AsImplementedInterfaces().AsSelf(); //容器 var container = builder.Build(); //注入改为Autofac注入 DependencyResolver.SetResolver( new AutofacDependencyResolver(container)); #endregion #region 2.注册MVC路由 var routes = RouteTable.Routes; routes.MapRoute( name: "Default" , url: "{controller}/{action}/{id}" , defaults: new { controller = "Home" , action = "Index" , id = UrlParameter.Optional } ); #endregion } |
3.带参数的控制器构造函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | public class HomeController : Controller { public HomeController(Say say) { } public string Index() { return "Hello World" ; } } public class Say { public string Get() { return "Hello World" ; } } |
4.浏览器访问~/
1.Install-Package Autofac.WebApi
2.由于WebAPI需要,引用系统自带Web.Http和Web.Http.WebHost
3.Application_Start添加此方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | protected void Application_Start( object sender, EventArgs e) { var configuration = GlobalConfiguration.Configuration; #region Autofac WebAPI注入 var builder = new ContainerBuilder(); builder.RegisterApiControllers(Assembly.GetExecutingAssembly()); builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly()).AsImplementedInterfaces().AsSelf(); var container = builder.Build(); configuration.DependencyResolver = new AutofacWebApiDependencyResolver(container); #endregion #region 注册Web API路由 configuration.Routes.MapHttpRoute( name: "DefaultApi" , routeTemplate: "api/{controller}/{id}" , defaults: new { id = RouteParameter.Optional }); #endregion } |
4.带参数的控制器构造函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | public class ValuesController : ApiController { public ValuesController(Say say) { } public string Get() { return "Hello World" ; } } public class Say { public string Get() { return "Hello World" ; } } |
5.浏览器访问~/api/values
1.Install-Package Autofac.Wcf
2.Application_Start添加此方法
1 2 3 4 5 6 7 8 9 10 | protected void Application_Start( object sender, EventArgs e) { #region WCF Autofac注入 var builder = new ContainerBuilder(); builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly()).AsImplementedInterfaces().AsSelf(); var container = builder.Build(); //WCF IOC容器 AutofacHostFactory.Container = container; #endregion } |
3.新建svc服务
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | public class TestService : ITestService { public TestService(Say say) { } public string DoWork() { return "Hello World" ; } } public class Say { public string Get() { return "Hello World" ; } } [ServiceContract] public interface ITestService { [OperationContract] string DoWork(); } |
4.svc指令中加一句:
Factory="Autofac.Integration.Wcf.AutofacServiceHostFactory, Autofac.Integration.Wcf"
5.wcftestclient
惭愧,好久没发博客了
【推荐】国内首个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 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义