使用Autofac动态注入启动Api服务 Autofac 动态注入启动Web Api 具体案例 功能实现 最终效果

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, 项目结构如下

使用Autofac动态注入启动Api服务
Autofac
动态注入启动Web Api
具体案例
功能实现
最终效果

  • Service A和Service B的controller存放在不同的项目中。
  • DynamicInjection是一个控制台项目,负责启动Web服务。
  • 当Build Service A和Service B项目时,会自动将生成的dll复制到DynamicInjection项目中的Services目录中。
  • 现在需要在DynamicInjection项目启动时,动态注入启动Services目录下的所有Web Api服务。

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
   

[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服务

   

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动态注入启动Api服务
Autofac
动态注入启动Web Api
具体案例
功能实现
最终效果

添加Autofac

程序启动成功之后,我们需要继续修改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服务被启动

使用Autofac动态注入启动Api服务
Autofac
动态注入启动Web Api
具体案例
功能实现
最终效果

然后我们在Postman中测试一下, Web Api是否能被正确调用

使用Autofac动态注入启动Api服务
Autofac
动态注入启动Web Api
具体案例
功能实现
最终效果

使用Autofac动态注入启动Api服务
Autofac
动态注入启动Web Api
具体案例
功能实现
最终效果

使用Autofac动态注入启动Api服务
Autofac
动态注入启动Web Api
具体案例
功能实现
最终效果