sun*_*nny 11 c# repository repository-pattern asp.net-core-mvc asp.net-core-3.0
我尝试使用存储库模式从我的数据库中获取数据我有 3 个项目
Bmu.Mode '这是用于创建数据库的模型'
Bmu.Repo '它有 2 个文件夹用于存储库,包括 contract/InewsRepository.cs' 和用于实现接口的 'Repository/NewsRepository'
Bmu.Api 用于从 Repo 项目调用数据
模型项目中的新闻类
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; }
}
}
Run Code Online (Sandbox Code Playgroud)
模型项目中的上下文类
namespace bmu.model
{
public class BmuContext : DbContext
{
public BmuContext(DbContextOptions<BmuContext> options): base(options)
{
}
public DbSet<News> News { get; set; }
}
}
Run Code Online (Sandbox Code Playgroud)
我在 Repo 项目中的界面
namespace bmu.repo.Contracts
{
public interface INewsRepository
{
Task<IEnumerable<News>> GetAllAsync();
Task<IEnumerable<News>> GetAllActiveAsync();
}
}
Run Code Online (Sandbox Code Playgroud)
在 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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
还添加
services.AddControllers();
services.AddSingleton<INewsRepository, NewsRepository>();
Run Code Online (Sandbox Code Playgroud)
在 Api 项目启动时,这是我的控制器
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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
但是当运行项目时我收到了这个错误
AggregateException:无法构建某些服务(验证服务描述符“ServiceType:bmu.repo.Contracts.INewsRepository Lifetime:Singleton ImplementationType:bmu.repo.IRepository.NewsRepository”时出错:无法解析“bmu”类型的服务。 model.BmuContext' 同时尝试激活 'bmu.repo.IRepository.NewsRepository'。)
也因为多项目添加 DbContext 与此
更新:
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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
这个错误有什么解决办法吗?
小智 23
我的错误是我注入的是服务类而不是接口
它是
//This is wrong
Private readonly DataSerive _dataService;
public void EmployeeHandler(DataSerive dataService)
{
_dataService = dataService;
}
Run Code Online (Sandbox Code Playgroud)
但应该是
//This is correct
Private readonly IDataSerive _dataService;
public void EmployeeHandler(IDataSerive dataService)
{
_dataService = dataService;
}
Run Code Online (Sandbox Code Playgroud)
这里DataService是处理操作的类, IDataService是接口
Ren*_*ena 18
首先,您需要更改:
services.AddSingleton<INewsRepository, NewsRepository>();
Run Code Online (Sandbox Code Playgroud)
到:
services.AddTransient<INewsRepository, NewsRepository>();
Run Code Online (Sandbox Code Playgroud)
其次,你需要注入IMemoryCache而不是MemoryCachein NewsRepository。
这是一个简单的演示,如下所示:
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();
}
Run Code Online (Sandbox Code Playgroud)
2.appsettings.json:
"ConnectionStrings": {
"Connectionstring": "Server=(localdb)\\mssqllocaldb;Database=Bmu;Trusted_Connection=True;MultipleActiveResultSets=true"
}
Run Code Online (Sandbox Code Playgroud)
3.新闻库:
public class NewsRepository : INewsRepository
{
private readonly BmuContext _context;
private readonly IMemoryCache _memoryCache;
public NewsRepository(BmuContext context, IMemoryCache memoryCache)
{
_context = context;
}
//...
}
Run Code Online (Sandbox Code Playgroud)
小智 10
您的 API 中存在生命周期类型不匹配。EntityFramework DbContext 是一个范围服务,您不能拥有 NewsRepository 的单例实例,因为它依赖于为每个请求生成的实例。
您要么必须使用 NewsRepository 作为范围服务,要么重新构建您的依赖关系解析,如以下 SO 答案所示:Use DbContext in ASP .Net Singleton Injected Class
sun*_*nny -11
原来是因为
private readonly IMemoryCache _memoryCache;
Run Code Online (Sandbox Code Playgroud)
当我删除它时,每个人都认为工作正常
| 归档时间: |
|
| 查看次数: |
62530 次 |
| 最近记录: |