ASP.NET Core 依赖注入
ASP.NET Core Autofac
ASP.NET Core 数据库访问
Autofac 6.0.0 documentation
1、管理 NuGet 程序包
添加 Autofac 、Autofac.Extensions.DependencyInjection 的引用
2、Startup.cs 代码
● 将 Startup.cs 中的 ConfigureServices 返回类型改为 IServiceProvider;
● 新建一个 RegisterAutofac 方法,把创建容器的代码放到其中;
● 新建一个 AutofacModuleRegister 类,继承 Autofac的Module;
● 重写 Module 的 Load 方法,来存放新组件的注入代码,避免 Startup.cs 文件代码过多混乱;
// This method gets called by the runtime. Use this method to add services to the container.
//public void ConfigureServices(IServiceCollection services)
public IServiceProvider ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
/// 注册Autofac
return RegisterAutofac(services);
}
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);
}
using Autofac;
using System.Reflection;
public class AutofacModuleRegister : Autofac.Module
{
//重写Autofac管道Load方法,在这里注册注入
protected override void Load(ContainerBuilder builder)
{
//以普通类的形式注册PlayPianoService
//builder.RegisterType<PlayPianoService>();
builder.RegisterType<Test>().AsSelf();
builder.RegisterType<Log>().SingleInstance().AsSelf();
builder.RegisterType<UserRepository>().As<IUserRepository>();
builder.RegisterGeneric(typeof(TestRepository<>)).As(typeof(ITestRepository<>));
//注册Service中的对象,Service中的类要以Service结尾,否则注册失败
builder.RegisterAssemblyTypes(GetAssemblyByName("WXL.Service")).Where(a => a.Name.EndsWith("Service")).AsImplementedInterfaces();
//注册Repository中的对象,Repository中的类要以Repository结尾,否则注册失败
builder.RegisterAssemblyTypes(GetAssemblyByName("WXL.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);
}
}
-------------------------- ASP.NET Core 3.X 使用 Autofac --------------------------
1、管理 NuGet 程序包
添加 Autofac.Extensions.DependencyInjection 的引用
2、Startup.cs 代码
public void ConfigureContainer(ContainerBuilder containerBuilder)
{
containerBuilder.RegisterModule<AutofacModuleRegister>();
}
3、Program.cs
添加 UseServiceProviderFactory(new AutofacServiceProviderFactory())
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseServiceProviderFactory(new AutofacServiceProviderFactory())
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
4、Test.WebAPI.Models
using Autofac;
using System.Reflection;
public class AutofacModuleRegister : Autofac.Module
{
//重写Autofac管道Load方法,在这里注册注入
protected override void Load(ContainerBuilder builder)
{
//以普通类的形式注册PlayPianoService
//builder.RegisterType<PlayPianoService>();
//注册Service中的对象,Service中的类要以Service结尾,否则注册失败
builder.RegisterAssemblyTypes(GetAssemblyByName("WXL.Service")).Where(a => a.Name.EndsWith("Service")).AsImplementedInterfaces();
//注册Repository中的对象,Repository中的类要以Repository结尾,否则注册失败
builder.RegisterAssemblyTypes(GetAssemblyByName("WXL.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);
}
}
5、
*
-------------------------- ASP.NET Core 依赖注入 --------------------------
IServiceCollection 负责注册
IServiceProvider 负责提供实例
服务生存期
AddTransient:暂时生存期服务,是每次从服务容器进行请求时创建的。 这种生存期适合轻量级、 无状态的服务。
AddScoped:作用域生存期服务,以每个客户端请求(连接)一次的方式创建。
AddSingleton:单一实例生存期服务,是在第一次请求时(或者在运行 Startup.ConfigureServices 并且使用服务注册指定实例时)创建的。
1、使用扩展方法 AddDbContext<TContext> 和 AddIdentityCore 向容器添加附加服务
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddSingleton(Configuration.GetConnectionString("DefaultConnection"));
services.AddScoped<IDbConnection, SqlConnection>();
#region 仓储注入
foreach (var item in GetAssemblyName("NurseCall.Repository"))
services.AddTransient(item.Key, item.Value);
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
#endregion
services.AddTransient<IApplicationService, ApplicationService>();
services.AddScoped<IApplicationService, ApplicationService>();
services.AddSingleton<IApplicationService, ApplicationService>();
services.AddTransient<IDbConnection>((sp) => new SqlConnection(Configuration.GetConnectionString("DefaultConnection")));
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
}
IServiceCollection、IServiceProvider使用
var services = new ServiceCollection();
// 默认构造
services.AddSingleton<IOperationSingleton, Operation>();
// 自定义传入Guid空值
services.AddSingleton<IOperationSingleton>(
new Operation(Guid.Empty));
// 自定义传入一个New的Guid
services.AddSingleton <IOperationSingleton>(
new Operation(Guid.NewGuid()));
var provider = services.BuildServiceProvider();
// 输出singletone1的Guid
var singletone1 = provider.GetService<IOperationSingleton>();
Console.WriteLine($"signletone1: {singletone1.OperationId}");
2、实体框架上下文
AddDbContext<TContext>
services.AddSingleton(Configuration.GetConnectionString("DefaultConnection"));
services.AddScoped<IDbConnection, SqlConnection>();
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();//获取header参数
*、批量注入
var assembly = Assembly.GetExecutingAssembly().DefinedTypes.Where(a => a.Name.EndsWith("Service") && !a.Name.StartsWith("I"));
foreach (var item in assembly)
{
services.AddTransient(item.GetInterfaces().FirstOrDefault(), item);
}
*、
*、Redis注入
services.AddSingleton<IRedisConnection>(k => { return new RedisConnection(6, Configuration["RedisConnectionString"]); });
方式一
services.AddSingleton<IConnectionMultiplexer, ConnectionMultiplexer>(x =>
{ return x.GetService<IRedisConnection>().ConnectionMultiplexer; });
方式二
var sp = services.BuildServiceProvider();
services.AddSingleton<StackExchange.Redis.IConnectionMultiplexer>((x) => { return sp.GetService<IRedisConnection>().ConnectionMultiplexer; });
方式三
services.AddScoped<ICacheManager, RedisCacheManager>();
在 Startup.cs 类 ConfigureServices 方法中注入 IHttpContextAccessor
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
*、Windows 窗体应用(WinForms)
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
ContainerBuilder builder = new ContainerBuilder();
builder.RegisterType<UserRepository>().As<IUserRepository>();
//注册当前程序集的所有类成员
builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly()).AsImplementedInterfaces().AsSelf();
builder.RegisterAssemblyTypes(Assembly.Load("Test.Repository")).Where(a => a.Name.EndsWith("Repository")).AsImplementedInterfaces().AsSelf();
builder.RegisterAssemblyTypes(Assembly.Load("Test.Business")).Where(a => a.Name.EndsWith("Business")).AsImplementedInterfaces().AsSelf();
IContainer container = builder.Build();
var serviceProvider = new AutofacServiceProvider(container);
var userBiz = container.Resolve<UserBusiness>();
var user = userBiz.GetUser();
}
}
*、
*、
*、
*、
*、
*、
*、
*、
*、
*、
*、
*、
*、
*、