Autofac(https://autofac.org/)是一款.NET的IOC组件,它能够和Owin, Web Api, ASP.NET MVC, .NET Core完美结合,帮助开发人员轻松解决程序中的依赖注入问题。git
所谓的动态注入启动Web Api需求, 就是在Web服务器启动时, 能够动态选择启动的Web Api 服务。github
之前使用IIS + Web Api的时候,咱们须要手动在IIS中部署全部的Web Api服务,并手动启动须要使用Web Api服务。api
在微软推出Owin以后,Owin Self Host + Web Api使开发人员能够脱离IIS服务器,使用命令行的方式启动并寄宿一个Web服务。Web服务启动时,咱们能够使用一些IOC容器,对Web Api进行动态注入启动。服务器
当前有一个项目(源码:https://github.com/lamondlu/DynamicInjection)中有2个Web Api服务ServiceA, ServiceB, 项目结构以下app
Service A测试
[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
ui
[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"; } }
首先咱们要在DynamicInjection项目添加Owin Self Host库。url
在Package Manage Console中输入如下命令命令行
Install-Package Microsoft.AspNet.WebApi.OwinSelfHost
3d
而后修改Program.cs代码,建立一个Startup类,使用Owin Self Host启动一个Web服务
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服务启动成功了
程序启动成功以后,咱们须要继续修改Program.cs。
首先,咱们须要引入Autofac库
在Package Manage Console中输入如下命令
Install-Package Autofac.WebApi2.Owin
引入完成以后,咱们须要在Programs.cs中添加代码,在启动服务以前,咱们须要从Services目录中读取全部的dll, 使用反射将其加载在内存中,若是发现dll存在继承自ApiController类的子类时,就将其注册到当前Web服务中。
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是否能被正确调用