Ger Hayden Ответов: 1

Службы .net core ведут себя по-разному


У меня есть две службы .net core 2.2, InitialisationHandler и WorkingTicketHandler, одна из которых содержит начальную информацию, а другая предназначена для хранения рабочего билета.
InitialisationHandler всегда имеет свою информацию готовой, когда его спрашивают, но WorkingTicketHandler всегда возвращает нулевую запись.

Мне нужно выяснить, как заставить WorkingTicketHandler удерживать свои данные точно так же, как это делает InitialisationHandler.

using VTModels.Other;

namespace VT_Online22.Infrastructure.Services
{
    /// <summary>
    /// Interface for the WorkingTicket Service
    /// </summary>
    public interface IWorkingTicketHandler
    {
        WorkingTicket GetWorkingTicket();
        void SaveWorkingTicket(WorkingTicket  argWorkingTicket);
        void ClearWorkingTicket();
    }

    /// <summary>
    /// WorkingTicket service class definition
    /// </summary>
    public class WorkingTicketHandler : IWorkingTicketHandler
    {

        public WorkingTicketHandler()
        {
            this.WorkingTicket = new WorkingTicket();
        }

        public WorkingTicket GetWorkingTicket()
        {
            return this.WorkingTicket;
        }

        public void SaveWorkingTicket(WorkingTicket arg_WorkingTicket)
        {
            this.WorkingTicket = arg_WorkingTicket;
        }

        public void ClearWorkingTicket()
        {
            this.WorkingTicket = new WorkingTicket();
        }

        private WorkingTicket WorkingTicket;
        private static readonly log4net.ILog logger = log4net.LogManager.GetLogger(typeof(WorkingTicketHandler));
    }
}



using Microsoft.Extensions.Configuration;
using SharedModels.Models;
using System.Collections.Generic;
using System.Threading.Tasks;
using VT_OnlineCore.Infrastructure.Other;
using VTModels.Models;

namespace VT_Online22.Infrastructure.Services
{
    /// <summary>
    /// Interface for the Initialization Service
    /// </summary>
    public interface IInitializationHandler
    {
        void Initialize();
        CConfigMasterBase GetConfig();
        IEnumerable<CScopeMasterBase> GetScopes(string clientId);
    }

    /// <summary>
    /// Initialization service class definition
    /// </summary>
    public class InitializationHandler : IInitializationHandler
    {

        public InitializationHandler(IConfiguration configTech)
        {
            ConfigurationTech = configTech;
            Initialize();
        }

        public void Initialize()
        {
            this.ldh = new LocalDataHandler(logger, this.ConfigurationTech);
            this.config = new CConfigMasterBase();
            LoadConfig();
        }

        public IEnumerable<CScopeMasterBase> GetScopes(string clientId)
        {
            IEnumerable<CScopeMasterBase> scopes = new List<CScopeMasterBase>();
            scopes =  this.ldh.GetScopes(clientId);
            return scopes;
        }
        public CConfigMasterBase GetConfig()
        {

            return this.config;
        }

        private async Task LoadConfig()
        {
            this.config =   this.ldh.GetConfig();           
        }

        private LocalDataHandler ldh;
        private CConfigMasterBase config;
        private IEnumerable<CScopeMasterBase> scopes;
        private static readonly log4net.ILog logger = log4net.LogManager.GetLogger(typeof(InitializationHandler));

        public IConfiguration ConfigurationTech { get; private set; }
    }
}



services.AddTransient<IInitializationHandler,InitializationHandler>();
services.AddTransient<IWorkingTicketHandler, WorkingTicketHandler>();


Что я уже пробовал:

Оба они добавляются в as transient в ConfigureServices и создаются как можно более идентично.

Существует одно ключевое отличие: InitialisationHandler имеет свои данные, созданные во время запуска его методом конструктора, и только после этого считывается из него, в то время как WorkingTicketHandler записывается контроллером и повторно считывается в том же контроллере (Get vs Post).

1 Ответов

Рейтинг:
5

Richard Deeming

Единственный способ GetWorkingTicket метод будет возвращен null это если вы сначала позвоните SaveWorkingTicket(null) в том же самом случае.

Я предполагаю, что вы имели в виду, что он возвращает пробел WorkingTicket например? Значение, которое вы храните в этом поле, не будет сохраняться между запросами - каждый запрос создает новый экземпляр вашего класса контроллера, который получит новый экземпляр вашего класса контроллера. IWorkingTicketHandler обслуживание.

Превращение этого сервиса в синглтон тоже не сработает. Это будет означать, что один рабочий билет был разделен между каждым пользователем вашего сервиса.

Вам нужно будет использовать состояние сеанса для хранения значения между запросами.

Состояние сеанса и приложения в ASP.NET ядро | Microsoft Docs[^]


Ger Hayden

Привет, Ричард, я использую состояние сеанса с некоторым успехом - я пытался достичь того же эффекта с помощью сервиса.

Richard Deeming

Службе все равно придется использовать состояние сеанса, если только вы не используете пользовательский контейнер DI, который поддерживает время жизни "за сеанс".

Похоже, вам может понадобиться сделать инъекцию IHttpContextAccessor сервис для доступа к сеансу из вашего класса обслуживания.

Ger Hayden

Мне нужно подумать об этом. У сеанса есть проблемы с конфиденциальностью, и я бы сделал их еще хуже, если бы у меня был сервисный подход к работе. Может быть, мне нужно сохранить эту информацию в таблице. Это то, что может превратиться в функцию, позволяющую пользователю сохранить покупку, не завершая ее, и вернуться к ней позже.