.Net 6.0 在尝试激活“EFCoreService”时无法解析类型“EFCoreRepository”的服务

问题描述 投票:0回答:1

我是 .Net 的新手,我正在尝试从头开始构建一个骨架项目。

首先,我编写了代表基本实体的IEntity类,简单易行如下:

    public interface IEntity
    {
        int Id { get; set; }
    }

然后我做了一个存储库界面,看起来像这样:

    public interface IRepository<T> where T : class, IEntity
    {
       //...... some methods 
    }

以及该接口的基本实现,如下所示:

    public class EFCoreRepository<TEntity, TContext> : IRepository<TEntity>
        where TEntity : class, IEntity
        where TContext : DBContext
    {
        protected readonly TContext _context;

        public EFCoreRepository(TContext context)
        {
            this._context = context;
        }
        // ...... some methods
    }

一个服务接口,看起来像这样

    public interface IService<TEntity> where TEntity : class, IEntity 
    {
       // ...... some methods
    }

以及该服务接口的基本实现,如下所示:

     public class EFCoreService<TEntity, TRepo> : IService<TEntity> 
        where TEntity : class, IEntity
        where TRepo : EFCoreRepository<TEntity, DBContext>
    {
        protected readonly TRepo _repository;

        public EFCoreService(TRepo repository) { 
            _repository = repository;
        }
        // ...... some methods
    }

我像这样在 program.cs 中注册了它们:

builder.Services.AddScoped<IRepository<IEntity>, EFCoreRepository<IEntity, DBContext>>();
builder.Services.AddScoped<IService<IEntity>, EFCoreService<IEntity, EFCoreRepository<IEntity, DBContext>>>();

您可能会注意到它是

DBContext
而不是
DbContext
。这不是错字,
DBContext
是我定制的课程,扩展了
DbContext
.

当我尝试构建项目时,出现了这个运行时错误:

Some services are not able to be constructed (Error while validating the service descriptor 
ServiceType: IService<IEntity> 
Lifetime: Scoped 
ImplementationType: EFCoreService<IEntity,EFCoreRepository<IEntity,DBContext>> 

Unable to resolve service for type EFCoreRepository<IEntity,DBContext> while attempting to activate EFCoreService<IEntity,EFCoreRepository<IEntity,DBContext>>

谁能找到这个错误的原因?任何建议将不胜感激。

------------------------------------ 补充问题-------- --------------------------

上面我想做的是注册一个公共服务,这样任何实现了基础服务的服务都可以有相应的实现方法。例如,如果有一个名为

Item
的实体,它的服务接口和实现是从基础服务扩展的,它们应该自动注册(准备作为依赖项注入)并具有基类实现的方法,如这个:

    public interface IItemService : IService<Item>
    {

    }

    public class ItemService : EFCoreService<Item, ItemRepository>
    {
        public ItemService(ItemRepository repository) : base(repository)
        {
        }
    }

是否可以通过上面的代码实现?

c# asp.net .net entity-framework asp.net-core
1个回答
0
投票

你可以试试下面的代码。
创建一个

DBContext
像表格一样进行测试。

    public class DBContext 
    {
        public IEnumerable<Product> products = new List<Product>()
        {
            new Product(){ Id=1 ,Name="Coke"},
            new Product(){ Id=2,Name="Pepsi"}

        };
    }
    public class Product
    {
        public int Id { get; set; }
        public string Name { get; set; }    
    }

TContext
添加到
IRepository
并创建一个
get()
方法进行测试。 (应该得到第一个产品名称是“可乐”)

    public class EFCoreRepository<TEntity, TContext> : IRepository<TEntity, TContext> where TEntity : class, IEntity
        where TContext : DBContext
    {
        protected readonly TContext _context;

        public EFCoreRepository(TContext context)
        {
            this._context = context;
        }
        // ...... some methods
        public string get()
        {
            return _context.products.FirstOrDefault().Name;
        }
    }

所以

IRepository.cs
变了

    public interface IRepository<TEntity, TContext> where TEntity : class, IEntity where TContext : class
    {
        string get();
    }

EFCoreService
中,注入
EFCoreRepository
而不是添加泛型
TRepo

    public class EFCoreService<TEntity> : IService<TEntity>
            where TEntity : class, IEntity
    {
        private readonly EFCoreRepository<TEntity, DBContext> _repository;

        public EFCoreService(EFCoreRepository<TEntity,DBContext> repository)
        {
            this._repository = repository;
        }
        // ...... some methods
        public string get()
        {
            
            return _repository.get();
        }
    }

所以

IService
也变了

    public interface IService<TEntity> where TEntity : class, IEntity
    {
        // ...... some methods
        string get();
    }

注册服务

program.cs
.

builder.Services.AddScoped<DBContext>();

builder.Services.AddScoped(typeof(EFCoreRepository<,>));
builder.Services.AddScoped(typeof(IRepository<,>), typeof(EFCoreRepository<,>));
builder.Services.AddScoped(typeof(IService<>), typeof(EFCoreService<>));

测试控制器

    [ApiController]
    public class ValuesController : ControllerBase
    {
        private readonly IService<Item> _service;

        public ValuesController(IService<Item> service)
        {
            this._service = service;
        }
        [HttpGet("test")]
        public string test()
        {
            return _service.get();
        }
    }

输出

参考这个答案:Nested Generics and Dependency Injection C#

© www.soinside.com 2019 - 2024. All rights reserved.