十年河东,十年河西,莫欺少年穷。
学无止境,精益求精。
准备如下工作:
新建一个Net6 webApi项目,并在该项目中引入:
新建类库MyInterface 和 MyService,项目构造如下
接口如下:
/// <summary>
/// 动物接口
/// </summary>
public interface IAnimal
{
void say();
}
实现类如下:
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("哼哼哼");
}
}
}
View Code
1、在webApi中引入autofac,并进行接口和实现类注入
builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory())
.ConfigureContainer<ContainerBuilder>(containerBuilder =>
{
containerBuilder.RegisterType<DogService>().As<IAnimal>();
containerBuilder.RegisterType<CatService>().As<IAnimal>();
containerBuilder.RegisterType<PigService>().As<IAnimal>();
});
View Code
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
@陈大六的波尔卡