C# autofac 在Net6中的使用
十年河东,十年河西,莫欺少年穷。
学无止境,精益求精。
准备如下工作:
新建一个Net6 webApi项目,并在该项目中引入:
新建类库MyInterface 和 MyService,项目构造如下
接口如下:
/// <summary> /// 动物接口 /// </summary> public interface IAnimal { void say(); }
实现类如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
namespace MyService { public class DogService : IAnimal { public void say() { Console.WriteLine("汪汪汪"); } } public class CatService : IAnimal { public void say() { Console.WriteLine("喵喵喵"); } } public class PigService : IAnimal { public void say() { Console.WriteLine("哼哼哼"); } } }
1、在webApi中引入autofac,并进行接口和实现类注入
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory()) .ConfigureContainer<ContainerBuilder>(containerBuilder => { containerBuilder.RegisterType<DogService>().As<IAnimal>(); containerBuilder.RegisterType<CatService>().As<IAnimal>(); containerBuilder.RegisterType<PigService>().As<IAnimal>(); });
2、在控制器中通过构造函数注入
namespace WebAppAutofac.Controllers { [Route("api/[controller]/[action]")] [ApiController] public class HomeController : ControllerBase { private readonly IAnimal Animal; private readonly IEnumerable<IAnimal> Animals; public HomeController( IAnimal animal, IEnumerable<IAnimal> animals,IServiceProvider provider,IComponentContext context) { Animal = animal; Animals = animals; // var MyAnimal_1 = provider.GetService<IAnimal>(); var MyAnimal_2 = context.Resolve<IAnimal>(); //// } [HttpGet] public ActionResult get() { Animal.say(); Console.WriteLine($"实现类的个数为:" + Animals.Count()); return Ok(); } } }
3、单抽象多继承的处理
项目中,动物接口由猫、狗、猪三个实现类继承,因此,上述代码构建的对象时最后一个注入的实现类对象,因此,我们有必要对单抽象多继承进行处理
关于单抽象多继承问题,可参考上篇博客:C# Autofac 构造函数注入,属性注入,方法注入
修改Program.cs注册autofac方法如下:
builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory()) .ConfigureContainer<ContainerBuilder>(containerBuilder => { containerBuilder.RegisterType<DogService>().Keyed<IAnimal>("dog"); containerBuilder.RegisterType<CatService>().Keyed<IAnimal>("cat"); containerBuilder.RegisterType<PigService>().Keyed<IAnimal>("pig"); });
控制器注入如下:
using Autofac; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using MyInterface; namespace WebAppAutofac.Controllers { [Route("api/[controller]/[action]")] [ApiController] public class HomeController : ControllerBase { // private readonly IAnimal dog; private readonly IAnimal cat; private readonly IAnimal pig; public HomeController(IServiceProvider provider,IComponentContext context) { // var s = provider.GetService<IAnimal>(); //// dog = context.ResolveKeyed<IAnimal>("dog"); cat = context.ResolveKeyed<IAnimal>("cat"); pig = context.ResolveKeyed<IAnimal>("pig"); } [HttpGet] public ActionResult get() { dog.say(); cat.say(); pig.say(); return Ok(); } } }
4、属性注入
由于本案例采用的是单抽象多继承,因此代码直接使用Keyed标识
修改Program.cs注册autofac方法如下
builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory()) .ConfigureContainer<ContainerBuilder>(containerBuilder => { containerBuilder.RegisterType<DogService>().Keyed<IAnimal>("dog"); containerBuilder.RegisterType<CatService>().Keyed<IAnimal>("cat"); containerBuilder.RegisterType<PigService>().Keyed<IAnimal>("pig"); //使继承自ControllerBase的控制器支持属性注入且排除掉ControllerBase自己 var ControllerBaseType = typeof(ControllerBase); containerBuilder.RegisterAssemblyTypes(typeof(Program).Assembly).Where(A => ControllerBaseType.IsAssignableFrom(A) && A != ControllerBaseType).PropertiesAutowired(); }); //修改微软默认设置 builder.Services.Replace(ServiceDescriptor.Transient<IControllerActivator, ServiceBasedControllerActivator>());
注意红色的两段代码
控制器代码如下:
using Autofac; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using MyInterface; namespace WebAppAutofac.Controllers { [Route("api/[controller]/[action]")] [ApiController] public class HomeController : ControllerBase { // public IAnimal dog { get; set; } public IAnimal cat { get; set; } public IAnimal pig { get; set; } public HomeController(IServiceProvider provider, IComponentContext context) { //dog = provider.GetService<IAnimal>(); dog = context.ResolveKeyed<IAnimal>("dog"); cat = context.ResolveKeyed<IAnimal>("cat"); pig = context.ResolveKeyed<IAnimal>("pig"); } [HttpGet] public ActionResult get() { dog.say(); cat.say(); pig.say(); return Ok(); } } }
over
@陈大六的波尔卡