c# - .NET Core 中的服务定位器不考虑范围

标签 c# asp.net-core .net-core inversion-of-control service-locator

我的部分代码需要使用 ServiceLocator,因为不支持构造函数注入(inject)。

我的启动类配置服务。我有一些是 transient 的,另一些是单例的,还有一些是作用域的。

例如:

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

在我的服务定义结束时,我有以下代码块,它设置了服务定位器。

var serviceProvider = services.BuildServiceProvider();
DependencyResolver.Current = new DependencyResolver();
DependencyResolver.Current.ResolverFunc = (type) =>
{
    return serviceProvider.GetService(type);
};

我注意到在给定的请求中,我没有从服务定位器接收到来自构造函数注入(inject)的相同实例。从服务定位器返回的实例似乎是单例并且不遵守范围。

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));
    }
}

我该如何解决这个问题?

最佳答案

我建议创建一个中间件,它将 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));
    }
}

不要忘记在 Startup.cs 的 Configure 方法中注册它:

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

关于c# - .NET Core 中的服务定位器不考虑范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53515885/

相关文章:

C# 对关闭 {} 的评论

c# - 将字符串更改为 const

asp.net-core - IdentityServer4: [Authorize(Roles = "Admin")] 即使 JWT token 具有 {"role": "Admin"} 声明,也不授予管理员用户访问权限

c# - Blazor UI 锁定

c# - Store 没有实现 IUserRoleStore<TUser> ASP.NET Core Identity

c# - 设置 ListView.ItemsSource 时的 StackOverflow

c# - 从并发异步任务访问共享资源是否安全? (C#)

asp.net-core - JWT token 未在远程服务器上验证,无法匹配 'kid' 错误

c# - Azure Functions 环境变量始终为 null

c# - 如何在每个实现的异步中抛出取消异常?