我在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
中有connectionString:public class AccountProvider : IUnitOfWork { private readonly LoginContext loginContext; private GenericRepository<Person> personRepository; <... and Others ...> }
而且,我的[[appsettings.json
"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%的时间将大量数据保留到数据库中,而不仅仅是帐户。因此,我建议您将其重命名为UnitOfWork
或DataAccessLayer
。