记录:如何使用ASP.NET Core和EnityFramework Core实现服务和数据分离
前情提要:
现有一个网站框架,包括主体项目WebApp一个,包含 IIdentityUser 接口的基架项目 A。用于处理用户身份验证的服务 AuthenticationService 位于命名空间B。用于保存数据的实体 User : IIdentityUser 位置项目C。项目之间的关系是B和C依赖项目A。
需求:
现在有一个新项目D,在这个项目里有一个DUser : IIdentityUser 。如何处理才能最优雅的在不添加引用和修改项目B的前提下,将用户保存至DUser。
实际例子:
在ASP.NET CORE中,有一个东西叫IdentityServer。里面就有这个东西,他写的是类似IdentityServerBuilder.AddService<TUser, TRole>()这种代码,如何实现?
解决方案:
1、新建一个泛类(这个类可以标记为internal,外部不需要了解,也不需要访问):
public class UserContext<TUser>
where TUser : class, IIdentityUser, new ()
{
public YourContext dbContext;
public UserContext(YourContext ctx) => dbContext = ctx; public DbSet<TUser> Users
{
get
{
return dbContext.Set<TUser>();
}
} public void SaveChanges()
{
dbContext.SaveChanges();
}
}
2、新建一个用以操作的服务(注意,所有需要的操作都往这个里面写,未来暴露的也是这个接口)
public class UserService<TUser> : IUserService
where TUser: class, IIdentityUser, new()
{
private UserContext<TUser> dbContext;
public UserService(YourContext ctx, IServiceProvider provider)
{
dbContext = new PermissionContext<TUser>(ctx.DbContext);
}
public TUser GetUserById(Guid id)
{
return dbContext.Users.FirstOrDefault(e => e.ID == id);
}
}
3、添加一个注射器
public static class AuthenticationInject
{
public static IServiceCollection AddAuthenticationContext<TUser>(this IServiceCollection services)
where TUser: IIdentityUser
{
var serviceType = typeof(UserService<>).MakeGenericType(typeof(TUser));
services.AddSingleton(typeof(IUserService), serviceType ); return services;
}
}
技术点:使用MakeGenericType方法可以动态加载泛类实例。如果类型是 UserService<TUser, TRole>,则写成 typeof(UserService<,>).MakeGenericType(typeof(T1), typeof(T2))
至此,我们就已经将泛类的类型名拆到了变量里面。然后就可以玩出一万种花样了。
4、在WebApp里,注入相关变量
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthenticationContext<DUser>();
}
分析依赖关系:
执行项目WebApp依赖A,B,D,B和D项目只依赖A。甚至于,这里还能再解耦。把函数AddAuthenticationContext从泛型函数改成 AddAuthenticationContext(Type userType),还可以再进一步,改成AddAuthenticationContext(string type),通过反射和配置来取类型,做到A项目和D项目解耦。
扩展性:
在未来,有新项目E,EUser。只需要将D和A解除分离,再将E和A进行关联。只需要修改 AddAuthenticationContext 函数,即可满足要求。当然,如果要有心情,你甚至可以搞一个自动发现的代码(比如我项目里就是这么搞的,自动分析IIdentityUser的对象,然后附加给Context,为了保证有多个实现时能正确附加,我做了一个Attribute用来标记这个项目要用哪个User)。再有心情还可以做成配置式的,反正你可以把EF Core摆出一万种姿势。
记录:如何使用ASP.NET Core和EnityFramework Core实现服务和数据分离的更多相关文章
- 【ASP.NET Core】EF Core - “影子属性” 深入浅出经典面试题:从浏览器中输入URL到页面加载发生了什么 - Part 1
[ASP.NET Core]EF Core - “影子属性” 有朋友说老周近来博客更新较慢,确实有些慢,因为有些 bug 要研究,另外就是老周把部分内容转到直播上面,所以写博客的内容减少了一点. ...
- 用ASP.NET Core构建可检测的高可用服务--学习笔记
摘要 随着现代化微服务架构的发展,系统故障的定位与快速恢复面临着诸多挑战,构建可检测的服务,帮助线上保障团队时刻掌控应用的运行状况越来越重要.本次分享会讲解如何让 ASP .NET Core 应用与现 ...
- asp.net core 使用中间件拦截请求和返回数据,并对数据进行加密解密。
原文:asp.net core 使用中间件拦截请求和返回数据,并对数据进行加密解密. GitHub demo https://github.com/zhanglilong23/Asp.NetCore. ...
- 使用 ASP.NET Core 3.1 的微服务开发指南
使用 ASP.NET Core 3.1 的微服务 – 终极详细指南 https://procodeguide.com/programming/microservices-asp-net-core/ A ...
- asp.net core + mysql + ef core + linux
asp.net core + mysql + ef core + linux 以前开发网站是针对windows平台,在iis上部署.由于这次需求的目标服务器是linux系统,就尝试用跨平台的.NET ...
- 003.ASP.NET Core tutorials--【Asp.net core 教程】
ASP.NET Core tutorials Asp.net core 教程 2016-10-14 1 分钟阅读时长 本文内容 1.Building web applications 构建web应用 ...
- ASP.NET Core教程【二】从保存数据看特有属性与服务端验证
前文索引: 在layout.cshtml文件中,我们可以看到如下代码: <a asp-page="/Index" class="navbar-brand" ...
- Asp.net Core中SignalR Core预览版的一些新特性前瞻,附源码(消息订阅与发送二进制数据)
目录 SignalR系列目录(注意,是ASP.NET的目录.不是Core的) 前言 一晃一个月又过去了,上个月有个比较大的项目要验收上线.所以忙的脚不沾地.现在终于可以忙里偷闲,写一篇关于Signal ...
- ABP 教程文档 1-1 手把手引进门之 ASP.NET Core & Entity Framework Core(官方教程翻译版 版本3.2.5)
本文是ABP官方文档翻译版,翻译基于 3.2.5 版本 官方文档分四部分 一. 教程文档 二.ABP 框架 三.zero 模块 四.其他(中文翻译资源) 本篇是第一部分的第一篇. 第一部分分三篇 1- ...
随机推荐
- Android项目目录结构模板以及简单说明
1) src 文件 编写java代码的文件目录,遵循java的命名规范.分包 2) gen 文件 包含了android的资源文件的标识符,是不需要程序员维护,是自动添加的 3) asse ...
- Linux Ubuntu 开发环境配置 ——最具生产力工具一览
Why Linux and Why exactly Ubuntu 首先这里就不做Mac,Linux,Windows三者之争了.只从个人角度分析下: Mac 不差钱(其实Mac作为超级本性价还行),不喜 ...
- 粒子群优化算法(PSO)之基于离散化的特征选择(FS)(一)
欢迎大家关注我们的网站和系列教程:http://www.tensorflownews.com/,学习更多的机器学习.深度学习的知识! 作者:Geppetto 在机器学习中,离散化(Discretiza ...
- 模块 sys shell参数获取
sys 参数获取 获取参数 sys模块是与python解释器交互的一个接口 sys.argv 命令行参数List,第一个元素是程序本身路径 sys.exit(n) 退出程序,正常退出时exit(0) ...
- elasticsearch在linux上的安装,Centos7.X elasticsearch 7.6.2
本文环境:Elasticsearch7.6.2目前最先版本 centos7.X JDK1.8 elasticsearch介绍 官网:https://www.elastic.co/cn/pr ...
- centos7 编译安装mysql5.7
mysql源码可以到官网下载 安装依赖包 yum -y install gcc gcc-c++ ncurses ncurses-devel bison libgcrypt perl make cmak ...
- ssh-add和ssh-agent
注: 因为在ssh-agent异常关闭或者新开窗口是会导致ssh-add找不到私钥,导致添加的私钥无效,所以下面使用keychain管理 ssh-add 参数 -l 查看代理中的私钥 -L 查看代理中 ...
- STM32F103ZET6独立看门狗
1.IWDG简介 STM32F103ZET6的独立看门狗(IWDG)是由内部LSI(内部约40KHZ低速时钟)时钟驱动的.由于IWDG是由内部低速时钟驱动,所以就算主时钟发生故障,IWDG依然能够工作 ...
- pyhton 信号量Semaphore和BoundedSemaphore
Semaphore和BoundedSemaphore两个,用起来好像没啥区别 都是定义信号量 sem=threading.BoundedSemaphore(5) sem=threading.Semap ...
- Java8 学习笔记--函数式接口与lambda表达式的关系
在java中,lambda表达式与函数式接口是不可分割的,都是结合起来使用的. 对于函数式接口,我们可以理解为只有一个抽象方法的接口,除此之外它和别的接口相比并没有什么特殊的地方.为了确保函数式接口的 ...