应用背景 net Core 三层的结构开发中很多人使用的还是手动注册的方式,就是写代码注册,一般是有一个类这里面全部都是手动注册XX接口对应的实现类是什么,这样的代码。我这个比较懒不喜欢总是写些无聊的代码,所以就自己封装了一个自动注册的类库,以下是类库的源码。 核心代码 AutoInjectRepository 类里的服务发现并自动注册是看服务实现类上有没有[AutoInject(typeof(IIndustryService), InjectType.Scope)]这个标签。有这个标签就会被注册
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using Microsoft.Extensions.DependencyInjection;
namespace CommonHelper.AutoInject.Service
{
public static class AutoInjectRepository
{
public static IServiceCollection AddAutoDi(this IServiceCollection serviceCollection)
{
foreach (Assembly item in Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory, "*.dll").Select(Assembly.LoadFrom).ToList())
{
List<Type> list = (from a in item.GetTypes()
where a.GetCustomAttribute<AutoInjectAttribute>() != null
select a).ToList();
if (list.Count <= 0)
{
continue;
}
foreach (Type item2 in list)
{
AutoInjectAttribute customAttribute = item2.GetCustomAttribute<AutoInjectAttribute>();
if (!(customAttribute?.Type == null))
{
switch (customAttribute.InjectType)
{
case InjectType.Scope:
serviceCollection.AddScoped(customAttribute.Type, item2);
break;
case InjectType.Single:
serviceCollection.AddSingleton(customAttribute.Type, item2);
break;
case InjectType.Transient:
serviceCollection.AddTransient(customAttribute.Type, item2);
break;
default:
throw new ArgumentOutOfRangeException();
}
}
}
}
return serviceCollection;
}
public static IServiceCollection AddAutoDiService(this IServiceCollection serviceCollection, string namespaceName)
{
foreach (Type item in getTypesInNamespace(namespaceName))
{
AutoInjectAttribute customAttribute = item.GetCustomAttribute<AutoInjectAttribute>();
if (!(customAttribute?.Type == null))
{
switch (customAttribute.InjectType)
{
case InjectType.Scope:
serviceCollection.AddScoped(customAttribute.Type, item);
break;
case InjectType.Single:
serviceCollection.AddSingleton(customAttribute.Type, item);
break;
case InjectType.Transient:
serviceCollection.AddTransient(customAttribute.Type, item);
break;
default:
throw new ArgumentOutOfRangeException();
}
}
}
return serviceCollection;
}
private static List<Type> getTypesInNamespace(string namespaceName)
{
return Assembly.Load(namespaceName).GetTypes().ToList();
}
}
}
Startup.cs 文件的服务自动注册功能,
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using LD.Admin.Models;
using Microsoft.OpenApi.Models;
using System.Reflection;
using System.IO;
using Swashbuckle.AspNetCore.SwaggerUI;
using CommonHelper.AutoInject.Service;
using LD.Admin.Service.RegisterService;
using LD.Admin.Repository.Factory;
using LD.Admin.Api.Models;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using System.Text;
using LD.Admin.Common;
using Microsoft.AspNetCore.SignalR;
using CommonHelper.AutoInject.Repository;
namespace LD.Admin.Api
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
//注册全局Configuration对象
ConfigurationManager.Configure(Configuration);
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "XX后台管理服务接口", Version = "v1" });
// 获取xml文件名
var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
// 获取xml文件路径
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
// 添加控制器层注释,true表示显示控制器注释
c.IncludeXmlComments(xmlPath, true);
c.ResolveConflictingActions(apiDescriptions => apiDescriptions.First());
c.DocumentFilter<HiddenApiFilter>();
});
services.Configure<TokenManagementModel>(Configuration.GetSection("JwtTokenConfig"));
var token = Configuration.GetSection("JwtTokenConfig").Get<TokenManagementModel>();
services.AddAuthentication(x =>
{
x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(x =>
{
x.RequireHttpsMetadata = false;
x.SaveToken = true;
x.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(token.Secret)),
ValidIssuer = token.Issuer,
ValidAudience = token.Audience,
ValidateIssuer = false,
ValidateAudience = false
};
});
services.AddScoped<IAuthenticateService, TokenAuthenticationService>();
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
//services.AddSingleton<NotificationHub>();
//services.AddSingleton<ChatHub>();
//"LD.Admin.Repository"
//RepositoryFactory.AutoRegisterService(string.Empty, "LD.Admin.Repository");
//RegisterServiceIoc.Register(services);
//services.AddAutoDi();
//业务层服务自动注入
services.AddAutoDiService("LD.Admin.Service");
//services.AddAutoDiService("LD.Admin.Repository");
//AutoFacFactory.AutoRegisterService("LD.Admin.Repository");
//调用AutoRegisterService方法实现数据访问层服务自动注册
RepositoryIocFactory.AutoRegisterService("LD.Admin.Repository");
//添加对AutoMapper的支持,会查找所有程序集中继承了 Profile 的类
// 配置AutoMapper
services.AddAutoMapper(typeof(AutoMapperConfigs));
services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());
services.AddControllers();
services.AddSignalR();
//跨域
var corsstring = Configuration.GetSection("Cors").Value;
string[] corsarray = corsstring.Split(',');
services.AddCors(options => options.AddPolicy("CorsPolicy",
builder =>
{
builder.AllowAnyMethod().AllowAnyHeader()
.WithOrigins(corsarray)
.AllowCredentials();
}));
//var assbembly = AppDomain.CurrentDomain.GetAssemblies().ToList();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
//注入请求。
ServiceLocator.SetServices(app.ApplicationServices);
//添加Swagger有关中间件
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "AdminAPI v1");
c.RoutePrefix = string.Empty;
c.DocExpansion(DocExpansion.None);
});
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseCors("CorsPolicy");
//启用认证
app.UseAuthentication();
//启用授权
app.UseAuthorization();
//var httpContextAccessor = app.ApplicationServices.GetRequiredService<IHttpContextAccessor>();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
var apiUrlConfig = Configuration.GetSection("ApiUrl").Value;
app.UseEndpoints(endpoints =>
{
//endpoints.MapHub<ChatHub>("/chatHub");
//endpoints.MapHub<ChatHub>("/chatHub").RequireCors(t => t.WithOrigins(new string[] { "http://localhost:8080" }).AllowAnyMethod().AllowAnyHeader().AllowCredentials());
endpoints.MapHub<ChatHub>("/chatHub").RequireCors(t => t.WithOrigins(new string[] { apiUrlConfig }).AllowAnyMethod().AllowAnyHeader().AllowCredentials());
//endpoints.MapHub<ChatHub>("/notifyHub").RequireCors(t => t.WithOrigins(new string[] { apiUrlConfig }).AllowAnyMethod().AllowAnyHeader().AllowCredentials());
endpoints.MapControllers();
});
}
}
}
服务层实现类的代码
/// <summary>
/// 行业表 业务逻辑层接口 实现类
/// </summary>
[AutoInject(typeof(IIndustryService), InjectType.Scope)]
public class IndustryService : BaseService<IIndustryRepository,int, IndustrySearchModel, IndustryModel>, IIndustryService
{
protected override IIndustryRepository Service
{
//get { return RepositoryFactory.Industry; }
get { return RepositoryIocFactory.GetRegisterImp<IIndustryRepository>(); }
}
protected override string ClassName
{
get { return "IndustryService"; }
}
}
控制器层的使用
/// <summary>
/// 行业接口
/// </summary>
public class IndustryController : BaseApiController
{
private IIndustryService _service;
/// <summary>
///
/// </summary>
/// <param name="service"></param>
public IndustryController(IIndustryService service)
{
_service = service;
}
/// <summary>
/// 获取分页列表
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
[HttpPost, Route("getlistbypage")]
public AjaxResultModel GetListByPage(IndustrySearchModel model)
{
var rspModel = new AjaxResultPageModel();
try
{
model.ValidatePageSize();
var pageModel = _service.GetListByPage(model, t => t.CreatedOn, OrderModeEnum.Desc);
if (pageModel != null && pageModel.Models.Count > 0)
{
rspModel.data = pageModel.Models;
rspModel.PageCount = pageModel.PageCount;
rspModel.RecordCount = pageModel.RecordCount;
rspModel.PageIndex = pageModel.PageIndex;
}
else
{
rspModel.message = "未查到相关数据";
}
rspModel.success = true;
}
catch (System.Exception ex)
{
rspModel.Error(ex.Message);
}
return rspModel;
}
/// <summary>
/// (详情)根据主键查询Model
/// </summary>
/// <param name="id">主键</param>
/// <returns></returns>
[HttpGet, Route("getmodelbyid")]
public AjaxResultModel GetModelById(int id)
{
var rspModel = new AjaxResultModel();
try
{
if (id > 0)
{
var model = _service.GetModelById(id);
if (model != null)
{
rspModel.Success(model);
}
else
{
rspModel.Success(model, "ID不存在");
}
}
else
{
rspModel.Warning("ID参数必传");
}
}
catch (Exception ex)
{
//AddLogError(_className, "GetModelById", ex.Message, ex, id, id);
rspModel.Error(ex.Message);
}
return rspModel;
}
}