从ASP.Net Core的UnitOfWork模式中的上下文构建

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

我在ASP.Net MVC项目中有一个Repository and UnitOfWork模式,现在我想将其移动到在UnitOfWork类中获取上下文的ASP.Net Core项目中。

上下文类:

public class LoginContext:DbContext
{

    public LoginContext(DbContextOptions<LoginContext> options)
        : base(options)
    {

    }
    public DbSet<Person> People { get; set; }
    <..other classes..>
}

GenericRepository:

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 ...>

UnitOfWork

public class AccountProvider : IUnitOfWork
{
    private readonly LoginContext loginContext;

    private GenericRepository<Person> personRepository;

    <... and Others ...>
}

而且,我的[[appsettings.json

中有connectionString:"ConnectionStrings": { "LoginContext": "Server=.\\MYSQLSERVER;Database=<DatabaseName>;Integrated Security=True;Trusted_Connection=True;"}

startup.cs] ::]中的ConfigureServices方法services.AddDbContext<LoginContext>(options => options.UseSqlServer(Configuration.GetConnectionString("LoginContext")));

现在在控制器中,我得到AccountProvider(UnitOfWork)的实例,并想使用它:

[Route("api/[controller]")] [ApiController] public class LoginController : ControllerBase { private readonly AccountProvider _accountProvider; public LoginController(AccountProvider account) { _accountProvider = account; } <... methods ...> }

[当我运行项目并将请求发送到控制器时,出现类似这样的异常:

InvalidOperationException:在尝试激活'MyProject.Controllers.LoginController'时无法解析'DataLogin.Context.AccountProvider'类型的服务

[我知道问题在于在控制器中获取上下文,并尝试在.Net Core中查看Internet以获得UnitOfWork模式。但不了解获取此方法的真实方法。请指导我。

我在ASP.Net MVC项目中有一个Repository and UnitOfWork模式,现在我想将其移动到我的ASP.Net Core项目中,该项目在UnitOfWork类中获取上下文。上下文类:公共类LoginContext:...

解决您的问题:

您没有注册AccountProvider(很有可能)。

您基本上看到的该错误意味着编译器认为您正在尝试将AccountProvider用作服务,但您忘记了在启动时进行注册。

// In startup.cs register a scoped AccountProvider as the concrete class for IUnitOfWork: services.AddScoped<IUnitOfWork, AccountProvider>()

这将解决您的错误。但是通过查看您的代码,我可以看到一些设计缺陷。您缺少通用存储库的接口。 

不使用接口的问题:

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

我的建议是创建一个IRepository类,并在您的UnitOfWork中使用它。

public interface IRepository<TEntity> where TEntity : class { // Code omitted for brevity. } public class GenericRepository<TEntity> : IRepository<TEntity> where TEntity : class { // Code omitted for brevity. } public class AccountProvider : IUnitOfWork { private LoginContext _context; // Use the IRepository class private IRepository<Person> _personRepository; public AccountProvider(LoginContext context) { _context = context; } // Initiate like this public IRepository<Person> PersonRepository { get { if (_personRepository == null) { _personRepository = new GenericRepository<Person>(_context); } return _personRepository; } } }

然后在命名UnitOfWork类时出现问题。

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

意思是,通过将其称为AccountProvider,建议此具体类所做的唯一事情是与帐户相关的操作。这几乎没有意义,因为您的应用程序有99%的时间将大量数据保留到数据库中,而不仅仅是帐户。因此,我建议您将其重命名为UnitOfWorkDataAccessLayer

asp.net-core-mvc repository-pattern dbcontext unit-of-work
1个回答
2
投票
解决您的问题:
© www.soinside.com 2019 - 2024. All rights reserved.