首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >AOP中的NAutowired

AOP中的NAutowired
EN

Stack Overflow用户
提问于 2022-05-02 20:51:17
回答 2查看 32关注 0票数 0

我的目标是将HttpContextAccessor注入我的记录器,因为我使用Metalama。伐木部分没问题,还能用。但是现在我想让我的代码更简洁,以后更通用。为此,我需要访问HttpContextAccessor。因为我不能在Metalama OverrideMethodAspect派生类中使用DI,所以我找到了一个很好的库,它允许我使用字段注入器注入值。在示例应用程序中,即使我将代码拆分到Service和Repository层,它也可以正常工作。我可以访问HttpContextAccessor。但在我的项目中,我无法获得注入到我的属性中的HttpContextAccessor实例。它总是空的。我的想法是封装类中需要的接口,使用NAutowired字段注入器注入所需的类,然后在OverrideMethodAspect重写方法中使用类的实例。

代码语言:javascript
复制
[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中总是为空。我将启动类更改为,如示例所示。

代码语言:javascript
复制
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);
EN

回答 2

Stack Overflow用户

发布于 2022-05-02 21:02:18

对于.NET 6及以后,

创建ServiceTool类,

代码语言:javascript
复制
public static class ServiceTool
{
        public static IServiceProvider ServiceProvider { get; private set; }

        public static IServiceCollection Create(IServiceCollection services)
        {
            ServiceProvider = services.BuildServiceProvider();
            return services;
        }
}

在program.cs管道中创建注册服务工具的扩展,

代码语言:javascript
复制
public static class ServiceCollectionExtensions
    {
        public static IServiceCollection AddDependencyResolvers(this IServiceCollection services)
        {
            services.AddSingleton<IHttpContextAccessor,HttpContextAccessor>();
            return ServiceTool.Create(services);
        }
    }

之后,您必须在program.cs中注册它

代码语言:javascript
复制
builder.Services.AddDependencyResolvers();

在这些步骤之后,您可以在应用程序中的任何地方访问HttpContextAccessor对象;

代码语言:javascript
复制
var httpContextAccessor = ServiceTool.ServiceProvider.GetService<IHttpContextAccessor>();
票数 0
EN

Stack Overflow用户

发布于 2022-06-02 08:19:20

关键是:

代码语言:javascript
复制
   var serviceFactory = new ServiceFactory();

如果希望通过依赖项注入ServiceFactory类的实例,那么ServiceFactory本身也应该通过依赖注入实例,如果使用new创建实例,则容器将无法工作。应该在ServiceFactory中注入LoggingAttribute实例

代码语言:javascript
复制
[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实例注入控制器。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72092269

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档