如何运用AutoFac在WebAPI中注入多个接口
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何运用AutoFac在WebAPI中注入多个接口相关的知识,希望对你有一定的参考价值。
参考技术A 关于控制反转和依赖注入的文章和书籍很多,对其定义也解释的也仁者见仁,这里就不赘述了,这是本人(只代表个人观点)的理解:控制反转(IoC/Inverse Of Control): 调用者不再创建被调用者的实例,由autofac框架实现(容器创建)所以称为控制反转。依赖注入(DI/Dependence injection) : 容器创建好实例后再注入调用者称为依赖注入。使用Autofac动态注入启动Api服务
原文:使用Autofac动态注入启动Api服务
Autofac#
Autofac(https://autofac.org/)是一款.NET的IOC组件,它可以和Owin, Web Api, ASP.NET MVC, .NET Core完美结合,帮助开发人员轻松解决程序中的依赖注入问题。
动态注入启动Web Api#
所谓的动态注入启动Web Api需求, 就是在Web服务器启动时, 可以动态选择启动的Web Api 服务。
以前使用IIS + Web Api的时候,我们需要手动在IIS中部署所有的Web Api服务,并手动启动需要使用Web Api服务。
在微软推出Owin之后,Owin Self Host + Web Api使开发人员可以脱离IIS服务器,使用命令行的方式启动并寄宿一个Web服务。Web服务启动时,我们可以使用一些IOC容器,对Web Api进行动态注入启动。
具体案例#
当前有一个项目(源码:https://github.com/lamondlu/DynamicInjection)中有2个Web Api服务ServiceA, ServiceB, 项目结构如下
- Service A和Service B的controller存放在不同的项目中。
- DynamicInjection是一个控制台项目,负责启动Web服务。
- 当Build Service A和Service B项目时,会自动将生成的dll复制到DynamicInjection项目中的Services目录中。
- 现在需要在DynamicInjection项目启动时,动态注入启动Services目录下的所有Web Api服务。
Service A
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 27 28 29 30 31 32 33 | [RoutePrefix( "api/ServiceA" )] public class ServiceAController : ApiController { [Route( "Values" )] [HttpGet] public List< string > Values() { return new List< string > { "value1" , "value2" }; } [Route( "Version" )] [HttpGet] public string Version() { return "Service A, version 1.0.0" ; } } |
Service B
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 27 28 29 30 31 32 33 | [RoutePrefix( "api/ServiceB" )] public class ServiceBController : ApiController { [Route( "Values" )] [HttpGet] public List< string > Values() { return new List< string > { "value3" , "value4" }; } [Route( "Version" )] [HttpGet] public string Version() { return "Service B, version 1.0.0" ; } } |
功能实现#
添加Owin Self Host#
首先我们要在DynamicInjection项目添加Owin Self Host库。
在Package Manage Console中输入以下命令
Install-Package Microsoft.AspNet.WebApi.OwinSelfHost
然后修改Program.cs代码,创建一个Startup类,使用Owin Self Host启动一个Web服务
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 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | class Program { static void Main( string [] args) { string baseAddress = "http://localhost:9002/" ; using (WebApp.Start<Startup>(url: baseAddress)) { Console.WriteLine( "App Server started." ); Console.ReadLine(); } } public class Startup { public void Configuration(IAppBuilder appBuilder) { } } } |
启动项目,如果出现以下界面,就表明Web服务启动成功了
添加Autofac#
程序启动成功之后,我们需要继续修改Program.cs。
首先,我们需要引入Autofac库
在Package Manage Console中输入以下命令
Install-Package Autofac.WebApi2.Owin
引入完成之后,我们需要在Programs.cs中添加代码,在启动服务之前,我们需要从Services目录中读取所有的dll, 使用反射将其加载在内存中,如果发现dll存在继承自ApiController类的子类时,就将其注册到当前Web服务中。
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 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | public class Startup { public void Configuration(IAppBuilder appBuilder) { //定义Autofac容器创建器 var builder = new ContainerBuilder(); //注入Api服务 BuildControllers(builder); //生成Autofac容器 var container = builder.Build(); //在Owin管道中加入Autofac中间件 appBuilder.UseAutofacMiddleware(container); HttpConfiguration config = new HttpConfiguration(); config.DependencyResolver = new AutofacWebApiDependencyResolver(container); config.MapHttpAttributeRoutes(); config.Routes.MapHttpRoute( name: "DefaultApi" , routeTemplate: "api/{controller}/{id}" , defaults: new { id = RouteParameter.Optional } ); appBuilder.UseAutofacWebApi(config); appBuilder.UseWebApi(config); } private void BuildControllers(ContainerBuilder builder) { var searchFolder = Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), SearchPath); foreach ( var file in Directory.EnumerateFiles(searchFolder, "*.dll" , SearchOption.AllDirectories)) { try { var assembly = Assembly.LoadFrom(file); var exportedTypes = assembly.GetExportedTypes(); if (exportedTypes.Any(t => t.IsSubclassOf( typeof (ApiController)))) { Console.WriteLine( "Started service " + assembly.FullName); builder.RegisterApiControllers(assembly).InstancePerRequest(); } } catch { } } } } |
最终效果#
启动项目之后,控制台结果如下,2个Web Api服务被启动
然后我们在Postman中测试一下, Web Api是否能被正确调用
以上是关于如何运用AutoFac在WebAPI中注入多个接口的主要内容,如果未能解决你的问题,请参考以下文章
AutoFac实现WebAPI依赖注入(EF以及Mysql)