I've got an error while start my application with GenericRepository. (No database provider has been configured for this DbContext.).

How can i modify mine GenericRepository to be able to resolve that? Here's my codes:

IRepository.cs

public interface IRepository<TEntity> where TEntity : class
{

    /*void Delete(TEntity entityToDelete);
    void Delete(object id);*/
    IEnumerable<TEntity> Get(
        Expression<Func<TEntity, bool>> filter = null,
        Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
        string includeProperties = "");

    TEntity GetById(object id);
    Task<TEntity> GetByIdAsync(object id);

    /*IEnumerable<TEntity> GetWithRawSql(string query,
        params object[] parameters);*/
    void Insert(TEntity entity);
    TEntity Update(long id, Action<TEntity> action);
    }

Generic Repository.cs

public class GenericRepository<TEntity> : IRepository<TEntity> where TEntity : class
    {
        internal Context context;
        internal DbSet<TEntity> dbSet;

        public GenericRepository(Context context)
        {
            this.context = context;
            this.dbSet = context.Set<TEntity>(); // here's the error (No database provider...)
        }

        public virtual IEnumerable<TEntity> Get(Expression<Func<TEntity, bool>> filter = null,
            Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
            string includeProperties = "")
        {
            IQueryable<TEntity> query = dbSet;

            if (filter != null)
            {
                query = query.Where(filter);
            }

            foreach (var includeProperty in includeProperties.Split
                (new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
            {
                query = query.Include(includeProperty);
            }

            if (orderBy != null)
            {
                return orderBy(query).ToList();
            }
            else
            {
                return query.ToList();
            }
        }

        public virtual TEntity GetById(object id)
        {
            return dbSet.Find(id);
        }

        public async Task<TEntity> GetByIdAsync(object id)
        {
            return await dbSet.FindAsync(id);
        }

        public virtual void Insert(TEntity entity)
        {
            dbSet.Add(entity);
            context.SaveChanges();
        }

        public virtual void Remove(object id)
        {
            TEntity entityToDelete = GetById(id);
            Remove(entityToDelete);
        }

        public void Remove(TEntity entityToDelete)
        {
            if (context.Entry(entityToDelete).State == EntityState.Detached)
            {
                dbSet.Attach(entityToDelete);
            }
            dbSet.Remove(entityToDelete);
        }

        public virtual void Update(TEntity entity)
        {
            dbSet.Attach(entity);
            context.Entry(entity).State = EntityState.Modified;
        }

        public TEntity Update(long key, Action<TEntity> action)
        {
            var model = dbSet.Find(key);
            if(model != null)
            {
                Update(model);
                action(model);
            }
            return model;
        }

    }

DependencyResolver.cs

public class DependencyResolver
    {
        public IServiceProvider ServiceProvider { get; }

        public DependencyResolver()
        {
            // Set up Dependency Injection
            IServiceCollection services = new ServiceCollection();

            ConfigureServices(services);
            ServiceProvider = services.BuildServiceProvider();
        }

        private void ConfigureServices(IServiceCollection services)
        {
            services.AddTransient(typeof(IRepository<>), typeof(GenericRepository<>));

            // Register DbContext class
            services.AddTransient(provider =>
            {
                var configService = provider.GetService<IConfigurationService>();
                //var connectionString = configService.GetConfiguration().GetConnectionString("uRP");
                var optionsBuilder = new DbContextOptionsBuilder<Context>();
                optionsBuilder.UseMySql("server=localhost;database=uRP;user=root;password=;", builder => builder.MigrationsAssembly(typeof(Context).GetTypeInfo().Assembly.GetName().Name));

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

            services.AddScoped<IAccountService, AccountService>();
            services.AddScoped<IUnitOfWork, UnitOfWork.UnitOfWork>();

        }
    }

Context.cs

public class Context : DbContext
{
public Context(DbContextOptions<Context> options) : base(options)
{

}

public Context()
{

}



public DbSet<AccountModel> Players { get; set; }
public DbSet<CharacterModel> Characters { get; set; }
}

And ContextTimeDesignFactory.cs

    class ContextDesignTimeFactory : IDesignTimeDbContextFactory<Context>
{
    public Context CreateDbContext(string[] args)
    {
        var resolver = new DependencyResolver();
        return resolver.ServiceProvider.GetService(typeof(Context)) as Context;
    }
}

There are all good. I've got an IAccountRepository, and ICharacterRepository and it's work good. How i can set the DbContextOptions in GenericRepository.cs?

1

There are 1 best solutions below

2
Ruslan Kamev On

Seems like a mistake with registration of Context.

You have DependencyResolver which used in ContextDesignTimeFactory. But how do you register Context within application?

When I try to register Context like this:

// Startup.cs
public void ConfigureServices(IServiceCollection services)
{
    ...

    services.AddTransient(provider =>
    {
        var optionsBuilder = new DbContextOptionsBuilder<Context>();
        optionsBuilder.UseMySql(
            "server=localhost;database=uRP;user=root;password=;",
            builder => builder.MigrationsAssembly(typeof(Context).GetTypeInfo().Assembly.GetName().Name));

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

    services.AddTransient(typeof(IRepository<>), typeof(GenericRepository<>));
}

there is no errors with resolving GenericRepository.

But when I change registration to

// Startup.cs
public void ConfigureServices(IServiceCollection services)
{
    ...

    services.AddTransient<Context>();

    services.AddTransient(typeof(IRepository<>), typeof(GenericRepository<>));
}

I've got exactly same exception at the same place.

Hope it help

P.S. For DbContext registration has a specific method AddDbContext