- A+
所属分类:.NET技术
ABP的模块注入非常不错,但是ABP太臃肿了,单独的模块或者功能不能抽出来单独使用,所以就想自己实现一个模块注入方法。
ABP的模块注入原理,是程序启动时扫描所有dll模块,进行批量注入,下面是实现方法。
一、模块抽象类
查看代码
/// <summary> /// 模块抽象类 /// </summary> public abstract class ICoreModule { /// <summary> /// 注册依赖方法 /// </summary> public abstract void Register(); /// <summary> /// 环境名称 /// </summary> public string EnvironmentName { get { return System.Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT"); } } /// <summary> /// 是否是开发环境 /// </summary> public bool IsDevelopment { get { return this.EnvironmentName == "Development"; } } /// <summary> /// 当前运行程序集名称 /// </summary> public string CurrentDomainName { get { //return AppDomain.CurrentDomain.GetType().FullName; return AppDomain.CurrentDomain.FriendlyName; } } }
二、每个子项目下添加DependencyModule类
查看代码
namespace Core { public class DependencyModule : ICoreModule { public override void Register() { //可以根据启动项目/项目环境来判断注入,例如单元测试项目 if (this.CurrentDomainName == "UnitTest" || this.IsDevelopment) { AutofacFactory.RegisterAssemblyTypes(Assembly.GetExecutingAssembly()); AutofacFactory.RegisterTypeAs(typeof(IAuthContext), typeof(AuthContext)); } else { AutofacFactory.RegisterAssemblyTypes(typeof(BaseRepository<>).Assembly, x => x.IsClass && !x.IsInterface, x => x.BaseType.IsGenericType && x.BaseType.GetGenericTypeDefinition() == typeof(BaseRepository<>)); AutofacFactory.RegisterAssemblyTypes(typeof(BaseEs<>).Assembly, x => x.IsClass && !x.IsInterface, x => x.BaseType.IsGenericType && x.BaseType.GetGenericTypeDefinition() == typeof(BaseEs<>)); } } } }
查看代码
namespace ServerApi { public class DependencyModule : ICoreModule { public override void Register() { AutofacFactory.RegisterAssemblyTypes(typeof(Startup).Assembly, x => x.IsClass && !x.IsInterface, x => x.BaseType.IsGenericType && x.BaseType.GetGenericTypeDefinition() == typeof(IHandler<>)); } } }
三、项目启动时,注入autofac容器
1、.netcore2.1
关键代码 return new AutofacServiceProvider(AutofacExt.InitAutofac(services));
查看代码
namespace WebApi { public class Startup { public Startup(IConfiguration configuration, IOptions<AppSetting> appConfiguration) { Configuration = configuration; _appConfiguration = appConfiguration; } public IConfiguration Configuration { get; } public IOptions<AppSetting> _appConfiguration; public IServiceProvider ConfigureServices(IServiceCollection services) { services.Configure<AppSetting>(Configuration.GetSection("AppSetting")); services.AddMvc(config => { config.Filters.Add<BasicFrameFilter>(); }) .AddControllersAsServices() .SetCompatibilityVersion(CompatibilityVersion.Version_2_1); services.AddMemoryCache(); services.AddCors(); var dbType = ((ConfigurationSection)Configuration.GetSection("AppSetting:DbType")).Value; if (dbType == Define.DBTYPE_SQLSERVER) { services.AddDbContext<BasicFrameDBContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DBContext"))); } else //mysql { services.AddDbContext<BasicFrameDBContext>(options => options.UseMySql(Configuration.GetConnectionString("DBContext"))); } services.AddHttpClient(); return new AutofacServiceProvider(AutofacExt.InitAutofac(services)); } public void Configure(IApplicationBuilder app, IHostingEnvironment env) { app.UseAuthentication(); if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/Error"); } app.UseStaticFiles(); app.UseCookiePolicy(); app.UseMvc(route => { route.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}"); route.MapRoute( name: "areas", template: "{area:exists}/{controller=Home}/{action=Index}/{id?}"); }); } } }
2、.netcore3.1
关键代码
.UseServiceProviderFactory(new AutofacServiceProviderFactory());
AutofacFactory.InitAutofac(builder);
builder.RegisterBuildCallback(scope =>
{
AutofacFactory.SetContainer((IContainer)scope);
});
查看代码
public class Program { public static void Main(string[] args) { CreateHostBuilder(args).Build().Run(); } public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); }) .UseServiceProviderFactory(new AutofacServiceProviderFactory()); }
查看代码
public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; } public void ConfigureServices(IServiceCollection services) { services.AddControllersWithViews().AddControllersAsServices(); services.AddControllers() .AddNewtonsoftJson(options => { options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();//修改属性名称的序列化方式,首字母小写 options.SerializerSettings.Converters.Add(new DateTimeConverter());//修改时间的序列化方式 options.SerializerSettings.Converters.Add(new LongConverter()); }); services.AddOptions(); services.AddMemoryCache(); services.AddCors(options => options.AddPolicy("cors", builder => { builder.AllowAnyMethod().SetIsOriginAllowed(_ => true).AllowAnyHeader().AllowCredentials(); })); services.AddSignalR(); } //Autofac注册 public void ConfigureContainer(ContainerBuilder builder) { AutofacFactory.InitAutofac(builder); builder.RegisterBuildCallback(scope => { AutofacFactory.SetContainer((IContainer)scope); }); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment() || env.IsEnvironment("Debug")) { app.UseDeveloperExceptionPage(); } app.UseCors("cors"); app.UseWebSockets(); //错误拦截中间件 app.UseMiddleware<ExceptionMiddleware>(); app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); endpoints.MapHub<MessageHub>("/MessageHub"); endpoints.Map("/", context => { context.Response.Redirect($"/api/Home/Index"); return Task.CompletedTask; }); }); } }
四、AutofacFactory类
查看代码
public static class AutofacFactory { private static IContainer _container; private static ContainerBuilder _builder; static AutofacFactory() { } public static IContainer InitAutofac(IServiceCollection services) { _builder = new ContainerBuilder(); RegisterAllModule(); if (services.All(u => u.ServiceType != typeof(IHttpContextAccessor))) { services.AddScoped(typeof(IHttpContextAccessor), typeof(HttpContextAccessor)); } _builder.Populate(services); _container = _builder.Build(); return _container; } public static IContainer InitAutofac() { _container = _builder.Build(); return _container; } public static void InitAutofac(ContainerBuilder builder) { _builder = builder; RegisterAllModule(); } public static void SetContainer(IContainer container) { _container = container; } public static IContainer GetContainer() { return _container; } public static ContainerBuilder GetBuilder() { return _builder; } public static void RegisterAssemblyTypes(params Assembly[] assemblies) { _builder.RegisterAssemblyTypes(assemblies); } public static void RegisterAssemblyTypes(Assembly assemblie, params Func<Type, bool>[] predicates) { var regBuilder = _builder.RegisterAssemblyTypes(assemblie); foreach (var pre in predicates) { regBuilder.Where(pre); } } public static void RegisterTypeAs(Type iServiceType, Type implementationType, AutofacLifetime lifetime = AutofacLifetime.InstancePerDependency) { var regbuilder = _builder.RegisterType(implementationType).As(iServiceType); if (lifetime == AutofacLifetime.SingleInstance) { regbuilder.SingleInstance(); } else if (lifetime == AutofacLifetime.InstancePerLifetimeScope) { regbuilder.InstancePerLifetimeScope(); } } public static void RegisterType(Type serviceType, AutofacLifetime lifetime = AutofacLifetime.InstancePerDependency) { var regbuilder = _builder.RegisterType(serviceType); if (lifetime == AutofacLifetime.SingleInstance) { regbuilder.SingleInstance(); } else if (lifetime == AutofacLifetime.InstancePerLifetimeScope) { regbuilder.InstancePerLifetimeScope(); } } /// <summary> /// 泛型类型注册 /// </summary> public static void RegisterGeneric(Type iServiceType, Type implementationType, AutofacLifetime lifetime = AutofacLifetime.InstancePerDependency) { var regbuilder = _builder.RegisterGeneric(implementationType).As(iServiceType); if (lifetime == AutofacLifetime.SingleInstance) { regbuilder.SingleInstance(); } else if (lifetime == AutofacLifetime.InstancePerLifetimeScope) { regbuilder.InstancePerLifetimeScope(); } } public static void RegisterGeneric(Type serviceType, AutofacLifetime lifetime = AutofacLifetime.InstancePerDependency) { var regbuilder = _builder.RegisterGeneric(serviceType); if (lifetime == AutofacLifetime.SingleInstance) { regbuilder.SingleInstance(); } else if (lifetime == AutofacLifetime.InstancePerLifetimeScope) { regbuilder.InstancePerLifetimeScope(); } } public static void RegisterType<iserviceType, implementationType>(AutofacLifetime lifetime = AutofacLifetime.InstancePerDependency) { var regbuilder = _builder.RegisterType<implementationType>().As<iserviceType>(); if (lifetime == AutofacLifetime.SingleInstance) { regbuilder.SingleInstance(); } else if (lifetime == AutofacLifetime.InstancePerLifetimeScope) { regbuilder.InstancePerLifetimeScope(); } } public static void Register<serviceType>(object obj, AutofacLifetime lifetime = AutofacLifetime.InstancePerDependency) { var regbuilder = _builder.Register(x => obj).As<serviceType>(); if (lifetime == AutofacLifetime.SingleInstance) regbuilder.SingleInstance(); else if (lifetime == AutofacLifetime.InstancePerLifetimeScope) regbuilder.InstancePerLifetimeScope(); } public static T Resolve<T>() { return _container.Resolve<T>(); } public static object Resolve(Type type) { return _container.Resolve(type); } /// <summary> /// 注册全部模块 /// </summary> public static void RegisterAllModule(params string[] dllnames) { var assembles = DependencyContext.Default.RuntimeLibraries.Select(x => x); if (dllnames.Count() > 0) { foreach (string dllname in dllnames) { assembles = assembles.Where(o => o.Name.StartsWith(dllname)); } var dlls = assembles.Select(o => Assembly.Load(new AssemblyName(o.Name))).ToArray(); } else { var dlls = assembles.Where(o => o.Type == "project") .Select(o => Assembly.Load(new AssemblyName(o.Name))).ToArray(); } //根据抽象类查找 var types = AppDomain.CurrentDomain.GetAssemblies() .SelectMany(a => a.GetTypes().Where(t => t.BaseType == typeof(ICoreModule) && t.BaseType.IsAbstract)) .ToArray(); //根据接口查找 //var types = AppDomain.CurrentDomain.GetAssemblies() // .SelectMany(a => a.GetTypes().Where(t => t.GetInterfaces().Contains(typeof(ICoreModule)))) // .ToArray(); foreach (var t in types) { var instance = (ICoreModule)Activator.CreateInstance(t); instance.Register(); } } } /// <summary> /// 生命周期 /// </summary> public enum AutofacLifetime { /// <summary> /// 默认生命周期,每次请求都创建新的对象 /// </summary> InstancePerDependency, /// <summary> /// 每次都用同一个对象 /// </summary> SingleInstance, /// <summary> /// 同一个Lifetime生成的对象是同一个实例 /// </summary> InstancePerLifetimeScope }