Error while validating the service descriptor 'ServiceType: INewsRepository Lifetime: Singleton ImplementationType: NewsRepository':

88,351

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>();
Share:
88,351
sunny
Author by

sunny

c# from 2003, .net Developer, xamarin, Angular,

Updated on September 17, 2021

Comments

  • sunny
    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
    sunny over 4 years
    I use services.AddScoped<INewsRepository, NewsRepository>();but get this error again
  • Sotiris Koukios-Panopoulos
    Sotiris Koukios-Panopoulos over 4 years
    How are you registering your BmuContext?
  • sunny
    sunny over 4 years
    services.AddDbContext<BmuContext>(); Also update my question
  • Sotiris Koukios-Panopoulos
    Sotiris Koukios-Panopoulos over 4 years
    I 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
    sunny over 4 years
    I do All of think, remove " private readonly IMemoryCache _memoryCache;" from Repository and avery think work fine
  • Rena
    Rena over 4 years
    If my answer is helpful,could you accept as answer?
  • Amin Golmahalle
    Amin Golmahalle about 4 years
    Your answer is not logical.
  • sunny
    sunny about 3 years
    I think its because of don't register IMemoryCache in startup.cs in service, it logical
  • Karim Alaa
    Karim Alaa about 3 years
    Is IMemoryCache was registerd in startup.cs?
  • Guy Levy
    Guy Levy almost 3 years
    Welcome 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
    malik masis over 2 years
    Also, you should sign Rena's answer as an accepted answer
  • Léon Pelletier
    Léon Pelletier about 2 years
    I'd also add to @malik comment: You should sign Rena's answer as an accepted answer.
  • UC57
    UC57 about 2 years
    In my case, i created non-public constructor. Resolved by creating it public and it works.