造轮子之属性注入配合懒加载构建服务抽象基类
1.Asp.Net Core造轮之旅:逐步构建自己的开发框架-目录2.asp.net core之Startup3.asp.net core之依赖注入4.asp.net core之中间件5.asp.net core之Host6.asp.net core之Kestrel7.asp.net core之配置8.asp.net core之Options9.asp.net core之日志10.asp.net core之路由11.asp.net core之异常处理12.asp.net core之HttpClient13.asp.net core之实时应用14.asp.net core之EfCore15.造轮子之自动依赖注入16.造轮子之日志17.造轮子之统一业务异常处理18.造轮子之统一请求响应格式19.造轮子之缓存20.造轮子之ORM集成21.造轮子之asp.net core identity22.造轮子之自定义授权策略23.造轮子之权限管理24.造轮子之多语言管理25.造轮子之角色管理26.造轮子之用户管理27.造轮子之菜单管理
28.造轮子之属性注入配合懒加载构建服务抽象基类
29.造轮子之EventBus30.造轮子之消息实时推送31.造轮子之种子数据32.造轮子之集成GraphQL33.造轮子之设置管理34.造轮子之文件管理35.造轮子之单层应用总结篇36.单层应用升级到多层应用137.单层应用升级到多层应用238.单层应用升级到多层应用3在前面实现管理API的时候,可以看到我们用的挺多功能是没有通过构造函数注入的。比如缓存DistributedCache,MemoryCache,对象映射Mapper,多语言L,当前用户CurrentUser等等。
这些全都初始化在WheelServiceBase以及WheelControllerBase中,可以通过属性注入完成这个操作,同时为了避免注入太多影响性能,可以配合懒加载实现除IServiceProvider以外的服务注入。
这样做的好处是可以很方便把我们常用的一些工具型服务打包到基类调用,不需要每个业务服务都需要重复注入,同时减少了我们业务服务构造器因为注入越来越臃肿的情况。
上代码:
namespace Wheel.Services
{
public abstract class WheelServiceBase
{
public IServiceProvider ServiceProvider { get; set; }
public SnowflakeIdGenerator SnowflakeIdGenerator => LazyGetService<SnowflakeIdGenerator>();
public GuidGenerator GuidGenerator => LazyGetService<GuidGenerator>();
public IHttpContextAccessor HttpContextAccessor => LazyGetService<IHttpContextAccessor>();
public IUnitOfWork UnitOfWork => LazyGetService<IUnitOfWork>();
public IMapper Mapper => LazyGetService<IMapper>();
public IMemoryCache MemoryCache => LazyGetService<IMemoryCache>();
public IDistributedCache DistributedCache => LazyGetService<IDistributedCache>();
public ILocalEventBus LocalEventBus => LazyGetService<ILocalEventBus>();
public IDistributedEventBus DistributedEventBus => LazyGetService<IDistributedEventBus>();
public ICurrentUser CurrentUser => LazyGetService<ICurrentUser>();
public IStringLocalizerFactory LocalizerFactory => LazyGetService<IStringLocalizerFactory>();
private IStringLocalizer _stringLocalizer = null;
public IStringLocalizer L {
get
{
if (_stringLocalizer == null)
_stringLocalizer = LocalizerFactory.Create(null);
return _stringLocalizer;
}
}
public T LazyGetService<T>() where T : notnull
{
return new Lazy<T>(ServiceProvider.GetRequiredService<T>).Value;
}
}
}
namespace Wheel.Controllers
{
[Authorize("Permission")]
public abstract class WheelControllerBase : ControllerBase
{
public IServiceProvider ServiceProvider { get; set; }
public SnowflakeIdGenerator SnowflakeIdGenerator => LazyGetService<SnowflakeIdGenerator>();
public GuidGenerator GuidGenerator => LazyGetService<GuidGenerator>();
public IUnitOfWork UnitOfWork => LazyGetService<IUnitOfWork>();
public IMapper Mapper => LazyGetService<IMapper>();
public IMemoryCache MemoryCache => LazyGetService<IMemoryCache>();
public IDistributedCache DistributedCache => LazyGetService<IDistributedCache>();
public ILocalEventBus LocalEventBus => LazyGetService<ILocalEventBus>();
public IDistributedEventBus DistributedEventBus => LazyGetService<IDistributedEventBus>();
public ICurrentUser CurrentUser => LazyGetService<ICurrentUser>();
public IStringLocalizerFactory LocalizerFactory => LazyGetService<IStringLocalizerFactory>();
private IStringLocalizer _stringLocalizer = null;
public IStringLocalizer L
{
get
{
if (_stringLocalizer == null)
_stringLocalizer = LocalizerFactory.Create(null);
return _stringLocalizer;
}
}
public T LazyGetService<T>() where T : notnull
{
return new Lazy<T>(ServiceProvider.GetRequiredService<T>).Value;
}
}
}
可以看到,只有public IServiceProvider ServiceProvider { get; set; }是通过属性注入的,别的服务都是通过LazyGetService方法获得实例。
LazyGetService则是通过懒加载的方法,调用ServiceProvider.GetRequiredService
注意,原生依赖注入是不支持使用属性注入功能的,需要第三方依赖注入组件支持,我们使用autofac的时候,若需要属性注入功能,则在注册注入时需要调用PropertiesAutowired()。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?