• NETCORE


    NETCORE - 依赖注入 - Autofac

     安装二个 Autofac 的 NuGet包 

    一. 逐个接口进入注册

    项目结构:

    新增 ITestService 接口

        public interface ITestService
        {
            string GetTest();
        }

    新增 类 

        public class TestService : ITestService
        {
            public string GetTest()
            {
                return "a! lalalalalla";
            }
        }

      

     大多时候,我们都是 以下方式进行依赖注入

    在startup.cs 中修改 ConfigureServices 方法

            public IServiceProvider ConfigureServices(IServiceCollection services)
            {
                services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
    
                //初始化容器
                var builder = new ContainerBuilder();
                //管道寄居
                builder.Populate(services);
                builder.RegisterType<TestService>().As<ITestService>();//TestService注入到ITestService

            ////注入的生命周期
            //builder.RegisterType<Service.TestService>().As<IService.ITestService>();//暂存生存期
            //builder.RegisterType<Service.TestService>().As<IService.ITestService>().InstancePerLifetimeScope();//范围生存期
            //builder.RegisterType<Service.TestService>().As<IService.ITestService>().SingleInstance();//单例生存期

           //构造
                var ApplicationContainer = builder.Build();
                //将AutoFac反馈到管道中
                return new AutofacServiceProvider(ApplicationContainer);
            }

    新增   TestController WebAPI控制器

        [Route("api/[controller]")]
        public class TestController : Controller
        {
    
            private IService.ITestService _testService;
    
            public TestController(IService.ITestService testService)
            {
                this._testService = testService;
            }
    
    
            [Route("GetTest")]
            [HttpGet]
            public string GetTest()
            {
                return this._testService.GetTest();
            }
        }

    查看结果,可读取到 GetTest 方法的 返回数据。

    随着业务的增长,接口跟实现类会越来越多,还需要手动一个个的注册依赖项,有时候会出现忘了写配置,导致程序报错,如果是多人开发,可能还会导致代码冲突,后期维护起来相对来说比较麻烦。

    二. Autofac自动注入  

    项目结构:

      

    准备一个 NETCORE.Autofac.Respository 类库

    新增 接口:IPersonRepository.cs,与实现类:PersonRepository.cs

        public interface IPersonRepository
        {
            string Eat();
        }
        public class PersonRepository : IPersonRepository
        {
            public string Eat()
            {
                return "吃饭";
            }
        }

    准备另一个 NETCORE.Autofac.PersonService类库

    新增 接口:IPersonService.cs,与实现类:PersonService.cs

        public interface IPersonService
        {
            string Eat();
        }
       public class PersonService:IPersonService
        {
    
            private IPersonRepository _personRespository;
            //通过构造函数注入 repository
            public PersonService(IPersonRepository personRespository)
            {
                _personRespository = personRespository;
            }
            public string Eat()
            {
                return _personRespository.Eat();
            }
        }

     在webapi项目中(NETCORE.Autofac):

    将Startup.cs中的ConfigureServices返回类型改为IServiceProvider,然后新起一个方法RegisterAutofac把创建容器的代码放到其中,然后建一个AutofacModuleRegister类继承Autofac的Module,然后重写Module的Load方法 来存放新组件的注入代码,避免Startup.cs文件代码过多混乱。

     startup.cs 文件

            public IServiceProvider ConfigureServices(IServiceCollection services)
            {
                services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
                 
                return RegisterAutofac(services);//注册Autofac
            }

    在startup.cs 中新增 RegisterAutofac 方法

            private IServiceProvider RegisterAutofac(IServiceCollection services)
            {
                //实例化Autofac容器
                var builder = new ContainerBuilder();
                //将Services中的服务填充到Autofac中
                builder.Populate(services);
                //新模块组件注册    
                builder.RegisterModule<AutofacModuleRegister>();
                //创建容器
                var Container = builder.Build();
                //第三方IOC接管 core内置DI容器 
                return new AutofacServiceProvider(Container);
            }

     新增 AutofacModuleRegister.cs 类

    using Autofac;
    using Autofac.Extensions.DependencyInjection;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Reflection;
    using System.Threading.Tasks;
    using AutofacIn = Autofac;//给引入的Autofac重命名,因为与命名空间 【NETCORE.Autofac】名称重复了
    
    namespace NETCORE.Autofac
    {
        public class AutofacModuleRegister : AutofacIn.Module
        {
            //重写Autofac管道Load方法,在这里注册注入
            protected override void Load(ContainerBuilder builder)
            {
                //注册Service中的对象,Service中的类要以Service结尾,否则注册失败
                builder.RegisterAssemblyTypes(GetAssemblyByName("NETCORE.Autofac.Service")).Where(a => a.Name.EndsWith("Service")).AsImplementedInterfaces();
                //注册Repository中的对象,Repository中的类要以Repository结尾,否则注册失败
                builder.RegisterAssemblyTypes(GetAssemblyByName("NETCORE.Autofac.Repository")).Where(a => a.Name.EndsWith("Repository")).AsImplementedInterfaces();
            }
            /// <summary>
            /// 根据程序集名称获取程序集
            /// </summary>
            /// <param name="AssemblyName">程序集名称</param>
            /// <returns></returns>
            public static Assembly GetAssemblyByName(String AssemblyName)
            {
                return Assembly.Load(AssemblyName);
            }
        }
    }

     新增 控制器 PersonController

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;
    using Microsoft.AspNetCore.Mvc;
    using NETCORE.Autofac.Service;
    
    // For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860
    
    namespace NETCORE.Autofac.Controllers
    {
        [Route("api/[controller]")]
        public class PersonController : Controller
        {
    
            private IPersonService _personService;
    
            //通过构造函数注入Service
            public PersonController(IPersonService personService)
            {
                this._personService = personService;
            }
    
            [Route("Eat")]
            [HttpGet]
            public JsonResult Eat()
            {
                var eatRes = this._personService.Eat();
    
                return new JsonResult(new { eat = eatRes });
            }
        }
    }

    调用 https://localhost:5001/api/person/eat: 

     

    三. 一个接口多个实现的情况

     

     在service项目中,

    增加接口:IPayService.cs

        public interface IPayService
        {
            string Pay();
        }

     增加两个实现类 AliPayService.cs 、WxPayService.cs

        public class AliPayService : IPayService
        {
            public string Pay()
            {
                return "支付宝支付";
            }
        }
        public class WxPayService : IPayService
        {
            public string Pay()
            {
                return "微信支付";
            }
        }

     在webapi 项目(NETCORE.Autofac)中,

    增加PayController.cs 控制器

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;
    using Microsoft.AspNetCore.Mvc;
    using NETCORE.Autofac.Service;
    
    // For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860
    
    namespace NETCORE.Autofac.Controllers
    {
        [Route("api/[controller]")]
        public class PayController : Controller
        {
            private IPayService _payService;
    
            public PayController(IPayService payService)
            {
                _payService = payService;
            }
    
    
            [Route("GetPayType")]
            [HttpGet]
            public JsonResult GetPayType()
            {
                string paytype = this._payService.Pay();
    
                return new JsonResult(new { paytype = paytype });
            }
    
        }
    }

    反问地址 https://localhost:5001/api/pay/getpaytype: 

    最后得到的是微信支付,因为两个对象实现一个接口的时候,注册时后面注册的会覆盖前面注册的。

    如果我想得到支付宝支付要怎么做呢?

    我们可以用另外一种注册方式RegisterType,修改注册方式AutofacModuleRegister.cs。

     单独注册这个接口。

            //重写Autofac管道Load方法,在这里注册注入
            protected override void Load(ContainerBuilder builder)
            {
                //注册Service中的对象,Service中的类要以Service结尾,否则注册失败
                builder.RegisterAssemblyTypes(GetAssemblyByName("NETCORE.Autofac.Service")).Where(a => a.Name.EndsWith("Service")).AsImplementedInterfaces();
                //注册Repository中的对象,Repository中的类要以Repository结尾,否则注册失败
                builder.RegisterAssemblyTypes(GetAssemblyByName("NETCORE.Autofac.Repository")).Where(a => a.Name.EndsWith("Repository")).AsImplementedInterfaces();
    
                //单独注册
                builder.RegisterType<WxPayService>().Named<IPayService>(typeof(WxPayService).Name);
                builder.RegisterType<AliPayService>().Named<IPayService>(typeof(AliPayService).Name);
            }  

    新增 webapi 控制器(PayEachController ):

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;
    using Autofac;
    using Microsoft.AspNetCore.Mvc;
    using NETCORE.Autofac.Service;
    
    // For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860
    
    namespace NETCORE.Autofac.Controllers
    {
        [Route("api/[controller]")]
        public class PayEachController : Controller
        {
            private IPayService _wxPayService;
            private IPayService _aliPayService;
            private IComponentContext _componentContext;//Autofac上下文
    
            public PayEachController(IComponentContext componentContext)
            {
                _componentContext = componentContext;
    
                //解释组件
                _wxPayService = _componentContext.ResolveNamed<IPayService>(typeof(WxPayService).Name);
                _aliPayService = _componentContext.ResolveNamed<IPayService>(typeof(AliPayService).Name);
            }
    
    
            [Route("GetPayType")]
            [HttpGet]
            public JsonResult GetPayType()
            {
                string paytype_wx = this._wxPayService.Pay();
                string paytype_ali = this._aliPayService.Pay();
    
                return new JsonResult(new { weixinPay = paytype_wx, aliPay = paytype_ali });
            }
        }
    }

    访问地址 https://localhost:5001/api/payEach/getpaytype 

     

     完成!


    附代码:https://gitee.com/wuxincaicai/NETCORE.git

    引用:

  • 相关阅读:
    实现Java中的ArrayList
    官方下拉刷新控件SwipeRefreshLayout的使用
    SpannableString的基本用法
    AlarmManager的使用
    在Android上使用Socket
    HttpURLConnection、HttpClient和Session
    Cocos2d入门及第一次运行时遇到的问题
    Thread的start和run的区别
    《重构》心得
    startActivityForResult()的用法(超好用啊)
  • 原文地址:https://www.cnblogs.com/1285026182YUAN/p/12985481.html
Copyright © 2020-2023  润新知