web-dev-qa-db-fra.com

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 le modèle de référentiel J'ai 3 projets

Bmu.Mode 'c'est pour que le modèle crée la base de données'

Bmu.Repo 'il a 2 dossiers pour le référentiel incluent le contrat/InewsRepository.cs' et 'Repository/NewsRepository' pour implémenter l'interface

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

cours d'actualités dans Model Project

namespace bmu.model
{
   public class News
   {
    public int Id { get; set; }

    public string SubTitle { get; set; }

    public string Title { get; set; }

    public string Summery { get; set; }
  }
}

classe de contexte dans le projet de modèle

namespace bmu.model
 {
   public class BmuContext : DbContext
    {
       public BmuContext(DbContextOptions<BmuContext> options): base(options)
      {

      }
    public DbSet<News> News { get; set; }
   }
}

Mon interface dans le projet Repo

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

implémenter 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();
    }

}
}

Ajoutez également

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

au démarrage du projet Api et c'est mon contrôleur

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();
    }
}
}

mais lors de l'exécution du projet, j'ai eu cette erreur

AggregateException: certains services ne peuvent pas être créés (erreur lors de la validation du descripteur de service 'ServiceType: bmu.repo.Contracts.INewsRepository Lifetime: Singleton ImplementationType: bmu.repo.IRepository.NewsRepository': impossible de résoudre le service pour le type 'bmu. model.BmuContext 'lors de la tentative d'activation de' bmu.repo.IRepository.NewsRepository '.)

également en raison de plusieurs projets ajouter DbContext avec ce

MISE À JOUR:

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);
    }
}
}

Existe-t-il une solution à cette erreur?

1
sunny

Comme Sotiris Koukios-Panopoulos -san comment

Je vois que vous configurez uniquement 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 -

dans mon cas, j'ai oublié de définir cela dans mon startup.cs

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

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

services.AddScoped<IMyTruckService, MyTruckService>();
0
rtfmpliz

Tout d'abord, vous devez changer:

services.AddSingleton<INewsRepository, NewsRepository>();

À:

services.AddTransient<INewsRepository, NewsRepository>();

Deuxièmement, vous devez injecter IMemoryCache 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:

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

3.NewsRepository:

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

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

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

Vous devez soit utiliser NewsRepository en tant que service de portée, soit restructurer votre résolution de dépendance, comme indiqué dans cette SO réponse: tiliser DbContext dans ASP Classe injectée .Net Singleton