我的目标是将HttpContextAccessor注入我的记录器,因为我使用Metalama。伐木部分没问题,还能用。但是现在我想让我的代码更简洁,以后更通用。为此,我需要访问HttpContextAccessor。因为我不能在Metalama OverrideMethodAspect派生类中使用DI,所以我找到了一个很好的库,它允许我使用字段注入器注入值。在示例应用程序中,即使我将代码拆分到Service和Repository层,它也可以正常工作。我可以访问HttpContextAccessor。但在我的项目中,我无法获得注入到我的属性中的HttpContextAccessor实例。它总是空的。我的想法是封装类中需要的接口,使用NAutowired字段注入器注入所需的类,然后在OverrideMethodAspect重写方法中使用类的实例。
[Service]
public class ServiceFactory
{
[Autowired(typeof(HttpContextAccessor))]
public IHttpContextAccessor HttpContextAccessor { get; set; }
}
public class LoggingAttribute : OverrideMethodAspect
{
public override dynamic OverrideMethod()
{
try
{
var serviceFactory = new ServiceFactory();
var result = meta.Proceed();
var user = (serviceFactory.HttpContextAccessor.HttpContext.User.Identity as ClaimsIdentity).Claims.FirstOrDefault(x => x.Type == "uid");
var loggedInUserIdentity = !string.IsNullOrEmpty(user?.Value) ?
$" => by user: {user.Value}" :
string.Empty;
}
}
}问题是,HttpContextAccessor在serviceFactory中总是为空。我将启动类更改为,如示例所示。
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.UseSerilog();
builder.Services.AddControllers()
.AddControllersAsServices();
builder.Services.Replace(ServiceDescriptor.Transient<IControllerActivator, NAutowiredControllerActivator>());
var assemblies = new List<string>
{
"aaa.Web.Api",
"aaa.Core",
"aaa.Comon"
};
builder.Services.AutoRegisterDependency(assemblies);发布于 2022-05-02 21:02:18
对于.NET 6及以后,
创建ServiceTool类,
public static class ServiceTool
{
public static IServiceProvider ServiceProvider { get; private set; }
public static IServiceCollection Create(IServiceCollection services)
{
ServiceProvider = services.BuildServiceProvider();
return services;
}
}在program.cs管道中创建注册服务工具的扩展,
public static class ServiceCollectionExtensions
{
public static IServiceCollection AddDependencyResolvers(this IServiceCollection services)
{
services.AddSingleton<IHttpContextAccessor,HttpContextAccessor>();
return ServiceTool.Create(services);
}
}之后,您必须在program.cs中注册它
builder.Services.AddDependencyResolvers();在这些步骤之后,您可以在应用程序中的任何地方访问HttpContextAccessor对象;
var httpContextAccessor = ServiceTool.ServiceProvider.GetService<IHttpContextAccessor>();发布于 2022-06-02 08:19:20
关键是:
var serviceFactory = new ServiceFactory();如果希望通过依赖项注入ServiceFactory类的实例,那么ServiceFactory本身也应该通过依赖注入实例,如果使用new创建实例,则容器将无法工作。应该在ServiceFactory中注入LoggingAttribute实例
[Service]
public class LoggingAttribute : OverrideMethodAspect
{
[Autowired]
public ServiceFactory serviceFactory;
public override dynamic OverrideMethod()
{
try
{
var result = meta.Proceed();
var user = (serviceFactory.HttpContextAccessor.HttpContext.User.Identity as ClaimsIdentity).Claims.FirstOrDefault(x => x.Type == "uid");
var loggedInUserIdentity = !string.IsNullOrEmpty(user?.Value) ?
$" => by user: {user.Value}" :
string.Empty;
}
}
}最后,还应该以同样的方式将LoggingAttribute实例注入控制器。
https://stackoverflow.com/questions/72092269
复制相似问题