网站首页 > 编程文章 正文
ABP的模块注入非常不错,但是ABP太臃肿了,单独的模块或者功能不能抽出来单独使用,所以就想自己实现一个模块注入方法。
ABP的模块注入原理,是程序启动时扫描所有dll模块,进行批量注入,下面是实现方法。
一、模块抽象类
查看代码
二、每个子项目下添加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(#34;/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
}
猜你喜欢
- 2024-09-09 搞懂事件——C# 的event的机制深度理解
- 2024-09-09 C 容易犯错的新手问题有哪些?(c语言容易犯错误的地方)
- 2024-09-09 想要使用C#编程创建3D PDF转换器?Aspose.PDF必不可少
- 2024-09-09 .NET 大牛之路 019 | C#基础:理解装箱与拆箱
- 2024-09-09 在CSI.EXE中使用C#脚本绕过应用白名单(含缓解方案)
- 2024-09-09 在C#中向IC卡(通常指智能卡或集成电路卡)写入数据
- 2024-09-09 C#编程中如何使用线程(c# 线程编程)
- 2024-09-09 c# 串口连接xbee模块并且发送AT命令
- 2024-09-09 iOS开发生涯的初恋:详解Objective-C多项改进
- 2024-09-09 c# 串口连接xbee模块并且发送AT命令设置NI值
你 发表评论:
欢迎- 06-24一个老爸画了超级有爱的365幅画 | 父亲节献礼
- 06-24产品小白看魏则西事件——用产品思维审视百度推广
- 06-24某教程学习笔记(一):13、脚本木马原理
- 06-24十大常见web漏洞——命令执行漏洞
- 06-24初涉内网,提权那些事(内网渗透提权)
- 06-24黑客命令第16集:47种最常见的**网站方法2/2
- 06-24铭说 | 一句话木马的多种变形方式
- 06-24Java隐藏的10倍效率技巧!90%程序员不知道的魔法方法(附代码)
- 最近发表
- 标签列表
-
- spire.doc (70)
- instanceclient (62)
- solidworks (78)
- system.data.oracleclient (61)
- 按键小精灵源码提取 (66)
- pyqt5designer教程 (65)
- 联想刷bios工具 (66)
- c#源码 (64)
- graphics.h头文件 (62)
- mysqldump下载 (66)
- libmp3lame (60)
- maven3.3.9 (63)
- 二调符号库 (57)
- git.exe下载 (68)
- diskgenius_winpe (72)
- pythoncrc16 (57)
- solidworks宏文件下载 (59)
- qt帮助文档中文版 (73)
- satacontroller (66)
- hgcad (64)
- bootimg.exe (69)
- android-gif-drawable (62)
- axure9元件库免费下载 (57)
- libmysqlclient.so.18 (58)
- springbootdemo (64)
本文暂时没有评论,来添加一个吧(●'◡'●)