Asp.net core mvc 在ASP.Net核心上的UnitOfWork模式中从上下文构建

Asp.net core mvc 在ASP.Net核心上的UnitOfWork模式中从上下文构建,asp.net-core-mvc,repository-pattern,dbcontext,unit-of-work,Asp.net Core Mvc,Repository Pattern,Dbcontext,Unit Of Work,我在ASP.NETMVC项目中有一个存储库和UnitOfWork模式,现在我想将其移动到我的ASP.Net核心项目中,该项目在UnitOfWork类中获取上下文 上下文类: public类LoginContext:DbContext { 公共登录文本(DbContextOptions选项) :基本(选项) { } 公共数据库集人物{get;set;} } 一般报告: 公共类通用存储,其中tenty:class { 私人登录文本_上下文; 私有数据库集实体表; 公共通用存储库(LoginCont

我在ASP.NETMVC项目中有一个存储库和UnitOfWork模式,现在我想将其移动到我的ASP.Net核心项目中,该项目在UnitOfWork类中获取上下文

上下文类:

public类LoginContext:DbContext
{
公共登录文本(DbContextOptions选项)
:基本(选项)
{
}
公共数据库集人物{get;set;}
}
一般报告:

公共类通用存储,其中tenty:class
{
私人登录文本_上下文;
私有数据库集实体表;
公共通用存储库(LoginContext上下文)
{
_上下文=上下文;
_entityTable=context.Set();
}
公共虚拟异步任务GetInfo(int-id)
{
返回等待实体表FindAsync(id);
}
工作单元

公共类AccountProvider:IUnitOfWork
{
私有只读登录文本登录文本;
私人通用存储库;
}
此外,我的appsettings.json中有connectionString:

“连接字符串”:{
“LoginContext”:“服务器=。\\MYSQLSERVER;数据库=;集成安全=真;可信连接=真;”}
和startup.cs中的ConfigureServices方法:

services.AddDbContext(options=>options.UseSqlServer(Configuration.GetConnectionString(“LoginContext”));
现在在controller中,我得到AccountProvider(UnitOfWork)的实例并希望使用它:

[Route("api/[controller]")]
[ApiController]
public class LoginController : ControllerBase
{
    private readonly AccountProvider _accountProvider;

    public LoginController(AccountProvider account)
    {
        _accountProvider = account;
    }
    <... methods ...>
}
[路由(“api/[控制器]”)]
[ApiController]
公共类登录控制器:ControllerBase
{
私有只读AccountProvider\u AccountProvider;
公共登录控制器(AccountProvider帐户)
{
_accountProvider=帐户;
}
}
当我运行project并向controller发送请求时,会出现如下异常:

InvalidOperationException:在尝试激活“MyProject.Controller.LoginController”时,无法解析“DataLogin.Context.AccountProvider”类型的服务

我知道问题出在controller中获取上下文,并尝试在.Net Core中查看Internet上的UnitOfWork模式。但不了解获取该模式的真正方法。请指导我..

解决问题: 您没有注册AccountProvider(很可能)

您看到的错误基本上意味着编译器看到您试图将AccountProvider用作服务,但您忘记在启动时注册它

//在startup.cs中,将作用域AccountProvider注册为IUnitOfWork的具体类:
services.AddScoped()
这将修复您的错误。但通过查看您的代码,我可以看到一些设计缺陷。 您缺少通用存储库的接口

不使用接口的问题: 通过不使用IGerericRepository接口,您将存储库与UnitOfWork类紧密耦合。这样,您的UnitOfWork类将几乎无法进行测试

我的建议是创建一个IRepository类,并在您的工作单元中使用它

公共接口假定,其中tenty:class
{
//为简洁起见,省略了代码。
}
公共类GenericRepository:i存储,其中tenty:class
{
//为简洁起见,省略了代码。
}
公共类AccountProvider:IUnitOfWork
{
私人登录文本_上下文;
//使用IRepository类
个人信息存储库;
公共帐户提供程序(LoginContext上下文)
{
_上下文=上下文;
}
//这样开始
公共IRepository PersonRepository
{
得到
{
if(_personRepository==null)
{
_personRepository=新的GenericRepository(_上下文);
}
return\u personRepository;
}
}
}
然后在命名UnitOfWork类时出现了问题

UnitOfWork类应该包含应用程序可以使用的每一个可能的数据库上下文。在控制器中调用的唯一对象是UnitOfWork类

这意味着,通过调用AccountProvider,您建议该具体类只执行与帐户相关的操作。这几乎毫无意义,因为应用程序99%的时间将大量数据持久化到数据库中,而不仅仅是帐户。因此,我建议您将其重命名为类似于
UnitOfWork
的名称de>DataAccessLayer

要解决您的问题: 您没有注册AccountProvider(很可能)

您看到的错误基本上意味着编译器看到您试图将AccountProvider用作服务,但您忘记在启动时注册它

//在startup.cs中,将作用域AccountProvider注册为IUnitOfWork的具体类:
services.AddScoped()
这将修复您的错误。但通过查看您的代码,我可以看到一些设计缺陷。 您缺少通用存储库的接口

不使用接口的问题: 通过不使用IGerericRepository接口,您将存储库与UnitOfWork类紧密耦合。这样,您的UnitOfWork类将几乎无法进行测试

我的建议是创建一个IRepository类,并在您的工作单元中使用它

公共接口假定,其中tenty:class
{
//为简洁起见,省略了代码。
}
公共类GenericRepository:i存储,其中tenty:class
{
//为简洁起见,省略了代码。
}
公共类AccountProvider:IUnitOfWork
{
私人登录文本_上下文;
//使用IRepository类
个人信息存储库;
公共帐户提供程序(LoginContext上下文)
{
_上下文=上下文;
}
//这样开始
公共IRepository PersonRepository
{
得到
{
if(_personRepository==null)
{
_personRepository=新的GenericRepository(_上下文);
}
return\u personRepository;
}
}
}
public class GenericRepository<TEntity> where TEntity : class
{
    private LoginContext _context;
    private DbSet<TEntity> _entityTable;

    public GenericRepository(LoginContext context)
    {
       _context = context;
       _entityTable = context.Set<TEntity>();
    }

    public virtual async Task<TEntity> GetInfo(int id)
    {
       return await _entityTable.FindAsync(id);
    }

    <... Other Methods ...>
public class AccountProvider : IUnitOfWork
{
    private readonly LoginContext loginContext;

    private GenericRepository<Person> personRepository;

    <... and Others ...>
}
"ConnectionStrings": {
"LoginContext": "Server=.\\MYSQLSERVER;Database=<DatabaseName>;Integrated Security=True;Trusted_Connection=True;"}
services.AddDbContext<LoginContext>(options => options.UseSqlServer(Configuration.GetConnectionString("LoginContext")));
[Route("api/[controller]")]
[ApiController]
public class LoginController : ControllerBase
{
    private readonly AccountProvider _accountProvider;

    public LoginController(AccountProvider account)
    {
        _accountProvider = account;
    }
    <... methods ...>
}