【问题标题】:Injecting a dependency to constructor of an attribute in C#在 C# 中将依赖项注入到属性的构造函数中
【发布时间】:2020-11-27 17:34:04
【问题描述】:

我有以下属性:

public class MultipleInteractivitiesAttribute : CheckBaseAttribute
{
    private readonly IInteractivityService _interactivityService;

    public MultipleInteractivitiesAttribute(IInteractivityService interactivityService)
    {
        _interactivityService = interactivityService;
    }

    public override Task<bool> ExecuteCheckAsync(CommandContext ctx, bool help)
    {
        var userId = ctx.User.Id;
        var cmdName = ctx.Command.QualifiedName;

        return Task.FromResult(!_interactivityService.CheckForUserInteractivity(userId, cmdName));
    }
}

下面的类有一个我使用属性的方法。

public class RecruitmentModule : BaseCommandModule
{
    private readonly IInteractivityService _interactivityService;

    public RecruitmentModule(IInteractivityService interactivityService)
    {
        _interactivityService = interactivityService;
    }
    
    [Command("apply"), MultipleInteractivities()]
    public async Task Apply(CommandContext ctx)
    {
          // some code here
    }
}

现在,当我使用MultipleInteractivities 作为Apply 方法上方的属性时,我遇到了问题。它希望我将参数传递给它的构造函数。

现在,因为我已经在 RecruitmentModule 类的构造函数中注入了 IInteractivityService。我尝试将它作为参数传递给我的MultipleInteractivities 属性。

像这样:

[Command("apply"), MultipleInteractivities(_interactivityService)]

但是,这会产生以下错误:

无法在静态上下文中访问非静态字段“_interactivityService”

所以我尝试在RecruitmentModule 类中将_interactivityService 字段设为静态,如下所示:

private static IInteractivityService _interactivityService;

现在,当它作为参数传递给我的 MultipleInteractivities 属性时,我收到以下错误。

属性构造函数参数“interactivityService”的类型为“DiscordBot.Core.Interfaces.IInteractivityService”,它不是有效的属性参数类型

如何将IInteractivityService 传递给我的MultipleInteractivitiesAttribute 而不会出错。

【问题讨论】:

    标签: c# asp.net-core .net-core c#-8.0 dsharp+


    【解决方案1】:

    您不需要 (and shouldn't) 将依赖项注入到属性构造函数中。相反,CommandContext 有一个 Services 属性返回一个 IServiceProvider,您可以使用它来解决依赖关系:

    public class MultipleInteractivitiesAttribute : CheckBaseAttribute 
    { 
        public override Task<bool> ExecuteCheckAsync(CommandContext ctx, bool help) 
        { 
            var userId = ctx.User.Id; 
            var cmdName = ctx.Command.QualifiedName; 
            var interactivityService = ctx.Services.GetService<IInteractivityService>();
    
            return Task.FromResult(!interactivityService.CheckForUserInteractivity(userId, cmdName)); 
        } 
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-17
      • 2019-04-20
      • 2011-02-02
      相关资源
      最近更新 更多