Error while validating the service descriptor 'ServiceType: INewsRepository Lifetime: Singleton ImplementationType: NewsRepository':
Solution 1
It was because of
private readonly IMemoryCache _memoryCache;
when i remove it every think work fine
Solution 2
Firstly,you need to change:
services.AddSingleton<INewsRepository, NewsRepository>();
To:
services.AddTransient<INewsRepository, NewsRepository>();
Secondly,you need to inject IMemoryCache
instead of MemoryCache
in NewsRepository
.
Here is a simple demo like below:
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;
}
//...
}
Solution 3
There is a lifetime type mismatch in your API. EntityFramework DbContext is a scoped service, and you cannot have a singleton instance of the NewsRepository, as it depends on an instance that is generated for each request.
You either have to use NewsRepository as a scoped service, or restructure your dependency resolution, like shown in this SO answer: Use DbContext in ASP .Net Singleton Injected Class
Solution 4
My Error was that I was injecting the service class instead of the interface
It was
//This is wrong
Private readonly DataSerive _dataService;
public void EmployeeHandler(DataSerive dataService)
{
_dataService = dataService;
}
But it should be
//This is correct
Private readonly IDataSerive _dataService;
public void EmployeeHandler(IDataSerive dataService)
{
_dataService = dataService;
}
Here DataService is the class that handles operation and IDataService is the interface
Solution 5
Like Sotiris Koukios-Panopoulos -san comment
I see you are only setting up the options for design time, not in your Startup.cs
. I expect a:
services.AddDbContext<BmuContext>(options => options.UseSqlite("your connection string"));
instead.
In my case, I forgot to set this in my Startup.cs
services.AddDbContext<myDbContext>(o => o.UseSqlServer(myConnectionString));
and I forgot to mention this, because I'm using interface an service
services.AddScoped<IMyTruckService, MyTruckService>();
Comments
-
sunny over 2 years
I try get data from my database with repository Pattern i have 3 project
Bmu.Mode 'this is for model to create database'
Bmu.Repo 'it have 2 folder for repository include contract/InewsRepository.cs' and 'Repository/NewsRepository' for implement Interface
Bmu.Api for invoke data from Repo project
news class in 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; } } }
context class in model project
namespace bmu.model { public class BmuContext : DbContext { public BmuContext(DbContextOptions<BmuContext> options): base(options) { } public DbSet<News> News { get; set; } } }
My interface in Repo project
namespace bmu.repo.Contracts { public interface INewsRepository { Task<IEnumerable<News>> GetAllAsync(); Task<IEnumerable<News>> GetAllActiveAsync(); } }
implement interface in 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(); } } }
Also add
services.AddControllers(); services.AddSingleton<INewsRepository, NewsRepository>();
in startup of Api project and this is my controller
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(); } } }
but when run project i got this error
AggregateException: Some services are not able to be constructed (Error while validating the service descriptor 'ServiceType: bmu.repo.Contracts.INewsRepository Lifetime: Singleton ImplementationType: bmu.repo.IRepository.NewsRepository': Unable to resolve service for type 'bmu.model.BmuContext' while attempting to activate 'bmu.repo.IRepository.NewsRepository'.)
also because of multi project add DbContext with this
UPDATE:
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); } } }
Is there any solution for this error ?
-
sunny over 4 yearsI use services.AddScoped<INewsRepository, NewsRepository>();but get this error again
-
Sotiris Koukios-Panopoulos over 4 yearsHow are you registering your BmuContext?
-
sunny over 4 yearsservices.AddDbContext<BmuContext>(); Also update my question
-
Sotiris Koukios-Panopoulos over 4 yearsI see you are only setting up the options for designtime, not in your Startup.cs. I expect a services.AddDbContext<BmuContext>(options => options.UseSqlite(your connection string)); instead
-
sunny over 4 yearsI do All of think, remove " private readonly IMemoryCache _memoryCache;" from Repository and avery think work fine
-
Rena over 4 yearsIf my answer is helpful,could you accept as answer?
-
Amin Golmahalle about 4 yearsYour answer is not logical.
-
sunny about 3 yearsI think its because of don't register IMemoryCache in startup.cs in service, it logical
-
Karim Alaa about 3 yearsIs IMemoryCache was registerd in startup.cs?
-
Guy Levy almost 3 yearsWelcome to SO. its not clear if your post is answering the original question. If you believe your post answers it, please elaborate why and how with more detail
-
malik masis over 2 yearsAlso, you should sign Rena's answer as an accepted answer
-
Léon Pelletier about 2 yearsI'd also add to @malik comment: You should sign Rena's answer as an accepted answer.
-
UC57 about 2 yearsIn my case, i created non-public constructor. Resolved by creating it public and it works.