Область действия не соблюдается с помощью сервисного локатора в .NET Core - PullRequest
0 голосов
/ 28 ноября 2018

Части моего кода должны использовать ServiceLocator, поскольку внедрение конструктора не поддерживается.

Мой класс запуска настраивает службы.У меня есть переходные, другие одноэлементные, другие ограничены.

Например:

services.AddScoped<IAppSession, AppSession>();
services.AddScoped<IAuthentication, Authentication>();
services.AddScoped<NotificationActionFilter>();

В конце определения моего сервиса у меня есть следующий блок кода, которыйустанавливает указатель службыЭкземпляры, возвращаемые из локатора службы, выглядят как одиночные и не учитывают область видимости.

Код для DependencyResolver выглядит следующим образом:

public class DependencyResolver
{
    public static DependencyResolver Current { get; set; }

    public Func<Type, object> ResolverFunc { get; set; }

    public T GetService<T>()
    {
        return (T)ResolverFunc(typeof(T));
    }
}

Как это исправить?

1 Ответ

0 голосов
/ 28 ноября 2018

Я бы предложил создать промежуточное ПО, которое установит ServiceProvider на тот, который используется в других местах:

public class DependencyResolverMiddleware
{
    private readonly RequestDelegate _next;

    public DependencyResolverMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task InvokeAsync(HttpContext httpContext)
    {
        DependencyResolver.Current.ResolverFunc = (type) =>
        {
            return httpContext.RequestServices.GetService(type);
        };

        await _next(httpContext);
    }
}

Кроме того, DependencyResolver должен быть обновлен для поддержки такого поведения:

public class DependencyResolver
{
    private static readonly AsyncLocal<Func<Type, object>> _resolverFunc = new AsyncLocal<Func<Type, object>>();

    public static DependencyResolver Current { get; set; }

    public Func<Type, object> ResolverFunc
    {
        get => _resolverFunc.Value;
        set => _resolverFunc.Value = value;
    }

    public T GetService<T>()
    {
        return (T)ResolverFunc(typeof(T));
    }
}

Не забудьте зарегистрировать его в методе Configure в Startup.cs:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    ...
    app.UseMiddleware<DependencyResolverMiddleware>();
}
...