Как избежать повторения условных логи c? - PullRequest
3 голосов
/ 28 апреля 2020

Я внедряю функции безопасности для моего. NET Базового приложения, и я снова и снова повторяю одну и ту же условную логику c. Есть ли способ, где я могу обобщить это в одном месте и применить его к сегментам, которые я хочу? Я вспоминаю использование делегатов или Fun c для такого рода вещей, но я не совсем уверен ... Есть идеи?

Ниже приведен код, который я пытаюсь написать один раз и применить в нескольких местах.

var currentUser = _httpContext.HttpContext.Session.GetCurrentUser<SessionContext>();
if(currentUser.Roles.Any())
{
    // ex query here. This could be any piece of code
    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");

Ответы [ 2 ]

0 голосов
/ 28 апреля 2020

Вот код, написанный на Swift. Я использую функционально-ориентированное программирование со словарями


struct User {
    var Roles: Set<String> = ["Doctor"]
}

func channel(user: User, _ roles: [String:() -> ()]) {
    for i in roles {
        if user.Roles.contains(i.key) { i.value() }
    }
}

let currentUser = User()
channel(user: currentUser,
       [
        "Doctor": {
        // Code for doctor
        },

        "Admin": {
        // Code for admin
        },

        "Blah": {
        // Code for blah
        },

        // You can even add more
    ]
)

Вы можете перечислить Создать перечисление
Почему перечисление?
Вы можете легко делать опечатки с помощью обычных строк
С Enum, если вы сделаете опечатку, Swift выдаст вам ошибку. Супер полезно!

enum UserRolls { case doctor, admin, patient, other(String) }
extension UserRolls: Hashable {}

struct User {
    var Roles: Set<UserRolls> = [.doctor]
}

func channel(user: User, _ roles: [UserRolls:() -> ()]) {
    for i in roles {
        if user.Roles.contains(i.key) { i.value() }
    }
}

let currentUser = User()
channel(user: currentUser,
       [
        .doctor: {
        // Code for doctor
        },

        .admin: {
        // Code for admin
        },

        .other("Blah"): {
        // Code for blah
        },

        // You can even add more
    ]
)
0 голосов
/ 28 апреля 2020

Вы можете создать новый 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();
}

В этом примере string является типом возврата, но это необязательно.

Наконец, зарегистрируйте этот сервис, используя строку

services.AddScoped<IMyHttpContextService, MyHttpContextService>();

где services - это

IServiceCollection services

Вместо AddScoped, вы можете использовать AddTransient или AddSingleton. Подробнее о времени жизни объектов и внедрении зависимостей . Эти три ключевых слова определяют срок службы объекта или, в данном случае, службы.

Регистрация начинается с Startup.cs (но, если честно, все начинается с Startup.cs, отсюда и название). Подробнее о Startup.cs . Другими словами, в Startup.cs вызовите метод

public void ConfigureServices(IServiceCollection services)

, который вызывается во время выполнения.

Внутри метода ConfigureServices вызовите другой, например MapInterfaces, для отображения интерфейса и передать его services. Метод MapInterfaces будет static методом внутри ServiceExtensions.cs.

public static void MapInterfaces(IServiceCollection services)
{
    services.AddScoped<IMyHttpContextService, MyHttpContextService>();
}

Еще лучше создать расширение метод Подробнее о методах расширения .

ServiceExtensions.cs - это класс static, который является условием для создания метода расширения. Метод расширения также должен быть static. Это будет сигнатура методов

static void MapInterfaces(this IServiceCollection services)

Конечно, не забудьте модификатор доступа (по крайней мере, такой же видимости, как у класса ServiceExtensions.cs). Обратите внимание, this ключевое слово.

Метод расширения MapInterfaces из ServiceExtensions.cs затем вызывается из ConfigureServices метода из Startup.cs следующим образом

services.MapInterfaces();

В конце концов, когда вы нужен метод CheckUserRoles, назовите его так

_myHttpContextService.CheckUserRoles();

РЕДАКТИРОВАТЬ : вы изменили реализацию метода, но это не изменит способ, которым вы могли бы сделать остальное решение.

...