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是否能被正確調用