我的部分代码需要使用 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/