【问题标题】:Passing requesting service object as null in .NET Core在 .NET Core 中将请求服务对象作为 null 传递
【发布时间】:2021-08-13 14:40:39
【问题描述】:

startup.cs 类中的我的 ConfigureService 方法

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers().AddNewtonsoftJson();

    services.AddSingleton<IConfiguration>(this.Configuration);

    // Load settings
    var settings = new BotSettings();
    Configuration.Bind(settings);

    services.AddDbContext<BotDbContext>(options => options.UseSqlServer(settings.ConnectionString));

    // Create the credential provider to be used with the Bot Framework Adapter.
    services.AddSingleton<ICredentialProvider, ConfigurationCredentialProvider>();
    services.AddSingleton<BotAdapter>(sp => (BotFrameworkHttpAdapter)sp.GetService<IBotFrameworkHttpAdapter>());

    // Register AuthConfiguration to enable custom claim validation for skills.
    services.AddSingleton(sp => new AuthenticationConfiguration { ClaimsValidator = new AllowedCallersClaimsValidator(settings.SkillConfiguration) });

    // register components.
    ComponentRegistration.Add(new DialogsComponentRegistration());
    ComponentRegistration.Add(new DeclarativeComponentRegistration());
    ComponentRegistration.Add(new AdaptiveComponentRegistration());
    ComponentRegistration.Add(new LanguageGenerationComponentRegistration());
    ComponentRegistration.Add(new QnAMakerComponentRegistration());
    ComponentRegistration.Add(new LuisComponentRegistration());

    // register Handoff 
    ConfigureHandOff(services, settings);

    // This is for custom action component registration.
    ComponentRegistration.Add(new CustomActionComponentRegistration());

    // Register the skills client and skills request handler.
    services.AddSingleton<SkillConversationIdFactoryBase, SkillConversationIdFactory>();
    services.AddHttpClient<BotFrameworkClient, SkillHttpClient>();
    services.AddSingleton<ChannelServiceHandler, SkillHandler>();
    services.AddApplicationInsightsTelemetry(settings?.ApplicationInsights?.InstrumentationKey ?? string.Empty);

    services.AddSingleton<ITelemetryInitializer, OperationCorrelationTelemetryInitializer>();
    services.AddSingleton<ITelemetryInitializer, TelemetryBotIdInitializer>();
    services.AddSingleton<IBotTelemetryClient, BotTelemetryClient>();
    services.AddSingleton<TelemetryLoggerMiddleware>(sp =>
    {
        var telemetryClient = sp.GetService<IBotTelemetryClient>();
        return new TelemetryLoggerMiddleware(telemetryClient, logPersonalInformation: settings?.Telemetry?.LogPersonalInformation ?? false);
    });
    services.AddSingleton<TelemetryInitializerMiddleware>(sp =>
    {
        var httpContextAccessor = sp.GetService<IHttpContextAccessor>();
        var telemetryLoggerMiddleware = sp.GetService<TelemetryLoggerMiddleware>();
        return new TelemetryInitializerMiddleware(httpContextAccessor, telemetryLoggerMiddleware, settings?.Telemetry?.LogActivities ?? false);
    });
    var storage = ConfigureStorage(settings);

    services.AddSingleton(storage);
    var userState = new UserState(storage);
    var conversationState = new ConversationState(storage);
    services.AddSingleton(userState);
    services.AddSingleton(conversationState);

    //Configure bot loading path
    var botDir = settings.Bot;
    var resourceExplorer = new ResourceExplorer().AddFolder(botDir);
    var defaultLocale = Configuration.GetValue<string>("defaultLanguage") ?? "en-us";
    var rootDialog = GetRootDialog(botDir);

    services.AddSingleton(resourceExplorer);

    resourceExplorer.RegisterType<OnQnAMatch>("Microsoft.OnQnAMatch");

    services.AddSingleton<IBotFrameworkHttpAdapter, BotFrameworkHttpAdapter>(s =>
        GetBotAdapter(storage, settings, userState, conversationState, s));

    var removeRecipientMention = settings?.Feature?.RemoveRecipientMention ?? false;

    //Adding Required Services

    services.AddTransient(typeof(IRepository<>), typeof(Repository<>));
    services.AddTransient<IUserService, UserService>();
    services.AddTransient<ICommunicationService, CommunicationService>();
    services.AddTransient<IMessageService, MessageService>();

    services.AddSingleton<IBot>(s =>
      new ComposerBot(
          s.GetService<IUserService>(),
          s.GetService<ConversationState>(),
          s.GetService<UserState>(),
          s.GetService<MessageRouter>(),
          s.GetService<MessageRouterResultHandler>()));
}

但是,当我尝试访问 UserService 对象时,它会在 ComposerBot.cs 类中传递空对象吗?可能是什么原因?

public ComposerBot(
    IUserService userService, 
    ConversationState conversationState, 
    UserState userState,
    MessageRouter messageRouter, 
    MessageRouterResultHandler messageRouterResultHandler)
{
    this.userService = userService; **showing NULL**
    this.conversationState = conversationState;
    this.userState = userState;
    this.dialogState = conversationState.CreateProperty<DialogState>("DialogState");
    this.messageRouter = messageRouter;
    this.messageRouterResultHandler = messageRouterResultHandler;
}

【问题讨论】:

  • 为什么要使用 lambda 注册 IBot?为什么不使用自动连线方法注册它,即:services.AddSingleton&lt;IBot, ComposerBot&gt;()?当您改用该方法时会发生什么?

标签: c# asp.net-core .net-core dependency-injection


【解决方案1】:

我认为您遇到了这个问题: https://github.com/dotnet/aspnetcore/issues/28684.

这是相关的: https://github.com/dotnet/aspnetcore/issues/17442

至少对我来说,一个临时的解决方案是将服务注入剃须刀页面,以将用户带到那里并将用户传递给服务。

注意:这应该是评论,但我没有足够的声誉来评论。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-21
    • 2021-02-07
    • 2012-07-20
    • 1970-01-01
    相关资源
    最近更新 更多