.Net Core自带注入有三种生命周期选项
1.AddTransient:每次都是新的。每次请求,都获取一个新实例。即使同一个请求内多次去获取也会取到新的实例。
2.AddScoped:作用域唯一。每次请求,都获取一个新的实例,同一个请求内多次获取,会得到同一个实例。
3.AddSingleton:全局唯一。每次获取都是同一个实例。
依赖注入的位置
项目Startup.cs下的ConfigureServices方法,把UserService注入。
public void ConfigureServices(IServiceCollection services)
{
//注入
services.AddTransient<IUserService,UserService>();
services.AddControllersWithViews();
services.AddOptions();
}
自动注入
如果有很多对象要注入的时候,一个个去手动注入明显不现实,就需要自动注入。
1.新建两个空接口类,用于标识需要注入的对象,IDenpendency为普通注入标识,IDenpendcySingleton全局唯一注入标识。
public interface IDenpendency
{
}
public interface IDenpendcySingleton
{
}
2.新建一个AutoDI类,用于扩展Startup.cs下方法ConfigureServices里面的IServiceCollection,这里只演示常用AddTransient和AddSingleton两种生命周期的注入,如果需要AddScoped也是同样的道理注入的。
public static class AutoDI
{
/// <summary>
/// 注入数据
/// </summary>
/// <param name="services"></param>
public static IServiceCollection AddDataService(this IServiceCollection services)
{
#region 依赖注入
var transientType = typeof(IDenpendency); //每次新建
var singletonType = typeof(IDenpendcySingleton); //全局唯一
//获取实现了接口IDenpendency和IDenpendcySingleton的程序集
var allTypes = AppDomain.CurrentDomain.GetAssemblies().SelectMany(a => a.GetTypes().Where(t => t.GetInterfaces().Contains(transientType) || t.GetInterfaces().Contains(singletonType)));
//class的程序集
var implementTypes = allTypes.Where(x => x.IsClass).ToArray();
//接口的程序集
var interfaceTypes = allTypes.Where(x => x.IsInterface).ToArray();
foreach (var implementType in implementTypes)
{
var interfaceType = interfaceTypes.FirstOrDefault(x => x.IsAssignableFrom(implementType));
//class有接口,用接口注入
if (interfaceType != null)
{
//判断用什么方式注入
if (interfaceType.GetInterfaces().Contains(transientType))
{
services.AddScoped(interfaceType, implementType);
}
else if (interfaceType.GetInterfaces().Contains(singletonType))
{
services.AddSingleton(interfaceType, implementType);
}
}
else //class没有接口,直接注入class
{
//判断用什么方式注入
if (implementType.GetInterfaces().Contains(transientType))
{
services.AddTransient(implementType);
}
else if (implementType.GetInterfaces().Contains(singletonType))
{
services.AddSingleton(implementType);
}
}
}
#endregion
return services;
}
}
修改Startup.cs下的ConfigureServices方法
public void ConfigureServices(IServiceCollection services)
{
//自动注入
AutoDI.AddDataService(services);
services.AddControllersWithViews();
services.AddOptions();
}
这里已经完成了,我们测试一下。
建一个IUserService.cs和UserService.cs看是否能注入。
public interface IUserService:IDenpendency
{
public string GetName();
}
public class UserService : IUserService
{
public string GetName()
{
return "test";
}
}
建一个 RoleService.cs为不需要接口的对象看是否能注入。
public class RoleService:IDenpendcySingleton
{
public string GetRoleName()
{
return "测试role";
}
}
在HomeController中通过构造函数注入。
public class HomeController : Controller
{
private readonly IUserService _userService;
private readonly RoleService _roleService;
public HomeController( IUserService userService, RoleService roleService)
{
_userService = userService;
_roleService = roleService;
}
public IActionResult Index()
{
return View();
}
public IActionResult test()
{
string name = _userService.GetName();
string roleName = _roleService.GetRoleName();
return Content($"name:{name},roleName:{roleName}");
}
}
运行程序,输出结果证明注入成功。
程序的目录结构。