我正在为我的.NET Core应用程序实现安全功能,并且发现自己一遍又一遍地重复相同的条件逻辑。有没有一种方法可以在一个地方对此进行概括并将其应用于我想要的细分市场?我记得使用委托或Func进行此类操作,但我不太确定...有什么想法吗?
下面是我试图编写一次并应用于多个地方的代码。
var currentUser = _httpContext.HttpContext.Session.GetCurrentUser<SessionContext>();
if(currentUser.Roles.Any())
{
var q = from u in _dbContext.Users
join d in _dbContext.Users on u.DoctorId equals d.Id into ud
from docU in ud.DefaultIfEmpty()
select new
{
User = u,
Doctor = docU
};
if(!currentUser.Roles.Contains("Administrator"))
{
if(currentUser.Roles.Contains("Doctor"))
{
//do something here
//ex.
q = q.Where(x => (x.Doctor != null ? x.Doctor.Id == currentUserId : false));
}
else if (currentUser.Roles.Contains("Patient"))
{
//do something else here
//ex.
q = q.Where(x => x.User.Id == currentUserId);
}
}
}
else
throw new Exception("No roles applied to logged in user");
您可以创建一个新的service
。
public class MyHttpContextService : IMyHttpContextService
{
IHttpContextAccessor _httpContext;
public MyHttpContextService(IHttpContextAccessor httpContext)
{
_httpContext = httpContext;
}
public string CheckUserRoles()
{
try
{
var currentUser = _httpContext?.HttpContext?.Session?.GetCurrentUser<SessionContext>();
if (currentUser != null)
{
if(currentUser.Roles.Any())
{
if(!currentUser.Roles.Contains("Administrator"))
{
if(currentUser.Roles.Contains("Doctor"))
{
//do something here
}
else if (currentUser.Roles.Contains("Patient"))
{
//do something else here
}
}
}
}
else
{
// if currentUser == null
}
}
catch (Exception ex)
{
// exception handling
}
}
}
通知电话
var currentUser = _httpContext.HttpContext.Session.GetCurrentUser<SessionContext>();
被替换为
var currentUser = _httpContext?.HttpContext?.Session?.GetCurrentUser<SessionContext>();
创建适当的interface
。
public interface IMyHttpContextService
{
string CheckUserRoles();
}
最后,使用线路注册此服务
services.AddScoped<IMyHttpContextService, MyHttpContextService>();
services
在哪里
IServiceCollection services
代替AddScoped
,您可以使用AddTransient
或AddSingleton
。 More about objects' lifetime and dependency injection。这三个关键字确定对象或服务(在这种情况下)的生命周期。
注册从Startup.cs
开始(但老实说,一切都从Startup.cs
开始,因此是名称)。 More about Startup.cs。换句话说,在Startup.cs
调用方法
public void ConfigureServices(IServiceCollection services)
由运行时调用。
内部方法ConfigureServices
调用另一个方法,例如MapInterfaces
,以进行接口映射并将其传递给services
。方法MapInterfaces
将是static
内部的ServiceExtension.cs
方法。
public static void MapInterfaces(IServiceCollection services)
{
services.AddScoped<IMyHttpContextService, MyHttpContextService>();
}
更好的是创建extension方法More about extension methods。
ServiceExtension.cs
是static
类,这是创建扩展方法的条件。扩展方法也需要为static
。这将是方法签名
static void MapInterfaces(this IServiceCollection services)
当然,请不要忘记访问修饰符(至少与ServiceExtension.cs
类具有相同的可见性)。注意this
关键字。
然后像这样从MapInterfaces
的ServiceExtension.cs
方法内部调用ConfigureServices
的扩展方法Startup.cs
services.MapInterfaces();
最后,每当需要方法CheckUserRoles
时,都像这样调用它
_httpContext.GetToken();