Nano Hash - криптовалюты, майнинг, программирование

Внедрение зависимостей и общий репозиторий Windows Forms C #

У меня есть приложение Windows Forms, в котором я пытаюсь использовать внедрение зависимостей для некоторых служб, поэтому я сначала выполнил следующую конфигурацию в Program.cs. Я регистрирую службы:

static class Program
{
    [STAThread]
    static void Main()
    {
        
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);

        var services = new ServiceCollection();
        ConfigureServices(services);

        using (ServiceProvider serviceProvider = services.BuildServiceProvider())
        {
            var mainForm = serviceProvider.GetRequiredService<SelecionarEmpresa>();
            Application.Run(mainForm);
        }
    }

    private static void ConfigureServices(ServiceCollection services)
    {

        services.AddDbContext<AnalistDbContext>();

        services.AddSingleton<MainForm>();
        services.AddScoped<Form1>();
        services.AddScoped<Form2>();
        services.AddScoped<Form3>();

        services.AddTransient<IEmpRepository, EmpRepository>();
        services.AddTransient<ISisRepository, SisRepository>();
    }
}

Пока все работает, есть 3 формы, которые я сделал для проверки функциональности, в Form1 я ввожу нужные мне сервисы:

private readonly ISisRepository _sisRepository;
private readonly IEmpRepository _empRepository;
public Form1(ISisRepository sistRepository,
             IEmpRepository empRepository)
{
    _sisRepository= sistRepository;
    _empRepository = empRepository;

    InitializeComponent();
}

И идея в том, чтобы использовать, например, _sisRepository для обновления записи, при первом сохранении он работает, если я снова нажимаю сохранить, возникает исключение, перед тем, как поставить исключение, я уже сообщаю вам, что я использую общий репозиторий, который является следующим:

public abstract class Repository<TEntity> : IRepository<TEntity> where TEntity : Entity, new()
{
    protected readonly AnalistDbContext Db;
    protected readonly DbSet<TEntity> DbSet;
    protected Repository(AnalistDbContext db)
    {
        Db = db;
        DbSet = db.Set<TEntity>();

        Db.ChangeTracker.AutoDetectChangesEnabled = false;

        var existeBanco = (Db.Database.GetService<IDatabaseCreator>() as RelationalDatabaseCreator).Exists();

        if (!existeBanco)
        {
            (Db.Database.GetService<IDatabaseCreator>() as RelationalDatabaseCreator).Create();
            (Db.Database.GetService<IDatabaseCreator>() as RelationalDatabaseCreator).CreateTables();
        }
    }
    public IEnumerable<TEntity> Buscar(Expression<Func<TEntity, bool>> predicate)
    {
        return DbSet.Where(predicate).AsNoTracking().ToList();
    }

    public virtual TEntity ObterPorId(Guid id)
    {
        return DbSet.AsNoTracking().FirstOrDefault(s => s.Id == id);
    }

    public virtual List<TEntity> ObterTodos()
    {
        return DbSet.AsNoTracking().ToList();
    }

    public void Adicionar(TEntity entity)
    {
        DbSet.Add(entity);
        SaveChanges();
    }

    public void Atualizar(TEntity entity)
    {
        DbSet.Update(entity);
        SaveChanges();
    }

    public void Remover(Guid id)
    {
        DbSet.Remove(new TEntity { Id = id });
        SaveChanges();
    }
    public int SaveChanges()
    {
        return Db.SaveChanges();
    }

    public void Dispose()
    {
        Db?.Dispose();
    }
}

Исключение составляет:

введите здесь описание изображения

Несмотря на ясность сообщения, я не мог понять, является ли это проблемой, вызванной использованием внедрения зависимостей в конструкторе формы и вызвавшей некоторую проблему в отношении экземпляра репозитория, кажется, что мой объект все еще такой же, как созданный ранее, потому что, как я уже сказал, эта ошибка возникает только при втором вызове. Если это действительно проблема, как вы можете ее решить? Или, когда дело доходит до оконных форм, могу ли я отказаться от использования внедрения зависимостей?


  • Можете ли вы упростить понимание проблемы? Это немного трудно следовать 16.09.2020
  • Принимая во внимание некоторые ответы, кажется, что это проблема, когда я обновляю запись во второй раз, так как она, кажется, уже отслеживается, видимо, я должен воссоздать свой контекст, иначе я получаю изображение вышеуказанного исключения. Но вот в чем проблема, хотелось бы понять, как правильно настроить этот сценарий. 16.09.2020

Ответы:


1

Когда вы обновляете элемент, DbContext начинает отслеживать этот элемент. Когда вы выполняете второе обновление, тот же DbContext пытается отслеживать другой элемент с тем же идентификатором. Это не проблема с внедрением зависимостей, это проблема со временем жизни внедренного AnalistDbContext и отслеживаемых им объектов.

Как правило, экземпляр DbContext создается для каждой операции, а не на протяжении всей формы. Это помогает предотвратить несоответствия, когда два пользователя пытаются изменить один и тот же объект. Вы можете попробовать:

  • Обновите Form1, чтобы использовать фабрику, которая может создавать репозитории, и удалять репозиторий после его использования.
  • Обновите репозиторий, чтобы использовать фабрику, которая может создавать AnalistDbContext и удалять контекст после его использования.

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

16.09.2020
  • Что касается вариантов настройки, у вас есть пример идеи для них? Я пробовал некоторые альтернативы, но безрезультатно. 16.09.2020
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..