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(); } }
5 Réponses :
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
J'utilise des services.AddScoped
Comment enregistrez-vous votre BmuContext?
services.AddDbContext
Je vois que vous ne configurez que les options pour la conception, pas dans votre Startup.cs. J'attends un services.AddDbContext
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>();
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 ?
C'était à cause de
private readonly IMemoryCache _memoryCache;
quand je le supprime, je pense que ça marche bien
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
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"));
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>();