如何避免重复条件逻辑?

问题描述 投票:2回答:1

我正在为我的.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");
c# .net-core delegates func code-reuse
1个回答
0
投票

您可以创建一个新的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,您可以使用AddTransientAddSingletonMore 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.csstatic类,这是创建扩展方法的条件。扩展方法也需要为static。这将是方法签名

static void MapInterfaces(this IServiceCollection services)

当然,请不要忘记访问修饰符(至少与ServiceExtension.cs类具有相同的可见性)。注意this关键字。

然后像这样从MapInterfacesServiceExtension.cs方法内部调用ConfigureServices的扩展方法Startup.cs

services.MapInterfaces();

最后,每当需要方法CheckUserRoles时,都像这样调用它

_httpContext.GetToken();
© www.soinside.com 2019 - 2024. All rights reserved.