1
votes

Erreur lors de la validation du descripteur de service 'ServiceType: INewsRepository Lifetime: Singleton ImplementationType: NewsRepository':

J'essaie d'obtenir des données de ma base de données avec un modèle de référentiel j'ai 3 projets

Bmu.Mode 'c'est pour le modèle de créer une base de données'

Bmu.Repo 'il a 2 dossiers pour le référentiel, notamment contract / InewsRepository.cs' et 'Repository / NewsRepository' pour l'interface d'implémentation

Bmu.Api pour appeler les données du projet Repo

classe de nouvelles dans le projet modèle

namespace bmu.model
{
public class BmuContextFactory : IDesignTimeDbContextFactory<BmuContext>
{
    public BmuContext CreateDbContext(string[] args)
    {
        var optionsBuilder = new DbContextOptionsBuilder<BmuContext>();
        optionsBuilder.UseSqlite("Data Source=bmu.db");

        return new BmuContext(optionsBuilder.Options);
    }
}
}

classe de contexte dans le projet modèle

namespace bmu.api.Controllers
{
[ApiController]
[Route("[controller]")]
public class NewsController : ControllerBase
{
     private readonly ILogger<NewsController> _logger;
     private readonly INewsRepository _newsRepository;

    public NewsController(ILogger<NewsController> logger,INewsRepository newsRepository)
    {
        _logger = logger;
        _newsRepository = newsRepository; 
    }
    [HttpGet]
    public async Task<IEnumerable<News>> Get()
    {
        return await _newsRepository.GetAllActiveAsync();
    }
}
}

Mon interface dans Projet de référentiel

services.AddControllers(); 
        services.AddSingleton<INewsRepository, NewsRepository>();

Mettre en œuvre l'interface dans bmu.repo

namespace bmu.repo.IRepository
{
 public class NewsRepository : INewsRepository
 {
    private readonly BmuContext _context;
    private readonly MemoryCache _memoryCache;

    public NewsRepository(BmuContext context, MemoryCache memoryCache)
    {
        _context = context;
        _memoryCache = memoryCache;
    }
    public async Task<IEnumerable<News>> GetAllAsync()
    {
        return await _context.News.ToListAsync(); 
    }
    public async Task<IEnumerable<News>> GetAllActiveAsync()
    {
      return   await _context.News.Where(x => x.Active).ToListAsync();
    }

}
}

Ajouter également

namespace bmu.repo.Contracts
{
  public interface INewsRepository
  {
    Task<IEnumerable<News>> GetAllAsync();
    Task<IEnumerable<News>> GetAllActiveAsync();
  }
}


0 commentaires

5 Réponses :


0
votes

Il existe une incompatibilité de type à vie dans votre API. EntityFramework DbContext est un service de portée, et vous ne pouvez pas avoir d'instance singleton de NewsRepository, car elle dépend d'une instance qui est générée pour chaque demande.

Vous devez soit utiliser NewsRepository comme service de portée, soit restructurer la résolution de vos dépendances, comme indiqué dans cette réponse SO: Utiliser DbContext dans ASP .Net Singleton Injected Class


4 commentaires

J'utilise des services.AddScoped (); mais j'obtiens à nouveau cette erreur


Comment enregistrez-vous votre BmuContext?


services.AddDbContext (); Mettre également à jour ma question


Je vois que vous ne configurez que les options pour la conception, pas dans votre Startup.cs. J'attends un services.AddDbContext (options => options.UseSqlite (votre chaîne de connexion)); au lieu



10
votes

Premièrement, vous devez changer:

public class NewsRepository : INewsRepository
{
    private readonly BmuContext _context;
    private readonly IMemoryCache _memoryCache;

    public NewsRepository(BmuContext context, IMemoryCache memoryCache)
    {
        _context = context;
    }
    //...
}

En:

"ConnectionStrings": {
    "Connectionstring": "Server=(localdb)\\mssqllocaldb;Database=Bmu;Trusted_Connection=True;MultipleActiveResultSets=true"  
}

Deuxièmement, vous devez injecter IMemoryCache code> au lieu de MemoryCache dans NewsRepository.

Voici une démo simple comme ci-dessous:

1.Startup.cs:

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersWithViews();
    services.AddSession();
    services.AddTransient<INewsRepository, NewsRepository>();
    services.AddDbContext<BmuContext>(options =>
                options.UseSqlServer(Configuration.GetConnectionString("Connectionstring")));
    services.AddMemoryCache();
}

2.appsettings.json:

services.AddTransient<INewsRepository, NewsRepository>();

3.NewsRepository:

services.AddSingleton<INewsRepository, NewsRepository>();


2 commentaires

Je fais tout de penser, supprimez "private readonly IMemoryCache _memoryCache;" du référentiel et avery pense que ça marche bien


Si ma réponse est utile, pourriez-vous accepter comme réponse ?



-8
votes

C'était à cause de

    private readonly IMemoryCache _memoryCache;

quand je le supprime, je pense que ça marche bien


2 commentaires

Votre réponse n'est pas logique.


Je pense que c'est à cause de ne pas enregistrer IMemoryCache dans startup.cs en service, c'est logique



0
votes

Comme Sotiris Koukios-Panopoulos -san comment

Je vois que vous ne configurez que les options pour la conception, pas dans votre Startup.cs . J'attends un:

services.AddScoped<IMyTruckService, MyTruckService>();

à la place.

Dans mon cas, j'ai oublié de le définir dans mon Startup.cs

services.AddDbContext<myDbContext>(o => o.UseSqlServer(myConnectionString));

et j'ai oublié de le mentionner, car j'utilise interface un service

services.AddDbContext<BmuContext>(options => options.UseSqlite("your connection string"));


0 commentaires

0
votes

J'ajoutais le service singleton qui injectait la classe DbContext .

services.AddTransient<FoodItemService>();

J'ai changé ci-dessus en ci-dessous (Ajout d'un portée du service transitoire ) et cela a fonctionné.

services.AddSingleton<WeatherForecastService>();


0 commentaires