如何在单独的类库 .net core 中使用 DbContext? [英] How to use DbContext in separate class library .net core?
问题描述
我正在尝试从类库中的 .net core 3.1 MVC 项目访问我的 dbcontext.目前我将我的数据库注入到 startup.cs
I'm trying to access my dbcontext from my .net core 3.1 MVC project in a class library. Currently I inject my database into the service collection in startup.cs
public class AppDbContext : DbContext
{
public DbSet<User> Users {get; set;}
public AppDbContext(DbContextOptions<AppDbContext> options)
: base(options)
{ }
protected override void OnModelCreating(ModelBuilder builder)
{
// Handles duplicate entry for email in user table
builder.Entity<User>()
.HasIndex(u => u.Email)
.IsUnique();
}
}
但是,我不确定如何在我的类库中访问这个 AppDbContext.我尝试像访问控制器一样访问它,但显然它不知道 DI 容器.
However, I'm unsure of how to access this AppDbContext in my class library. I tried accessing it like i would a controller, but obviously it doesn't know about the DI container.
更多信息:此库用于发出的常见请求.它必须始终与主 Web 应用程序分开,并且用户永远不必在此类库中编写代码.因此,我需要能够从类库访问主 Web 项目中的 dbcontext.
推荐答案
正如您所说,您正在开发类库以使用库客户端传递的任何 DbContext
那么您必须这样做如下:
As you said you are developing the class library to use any DbContext
passing by the client of the library then you have to do as follows:
首先考虑您的类库具有以下接口和类,您的 DbContext
将用于:
First considering your class library has following interfaces and classes where your DbContext
will be used:
public interface IUnitOfWork
{
IRepository<T> Repository<T>() where T : class;
Task SaveChangesAsync();
}
internal class UnitOfWork : IUnitOfWork
{
private readonly DbContext _dbContext;
private Hashtable _repositories;
public UnitOfWork(DbContext dbContext)
{
_dbContext = dbContext;
}
public IRepository<T> Repository<T>() where T : class
{
if (_repositories == null)
_repositories = new Hashtable();
var type = typeof(T).Name;
if (!_repositories.ContainsKey(type))
{
var repositoryType = typeof(Repository<>);
var repositoryInstance =
Activator.CreateInstance(repositoryType.MakeGenericType(typeof(T)), _dbContext);
_repositories.Add(type, repositoryInstance);
}
return (IRepository<T>)_repositories[type];
}
public async Task SaveChangesAsync()
{
await _dbContext.SaveChangesAsync();
}
}
public interface IRepository<TEntity> where TEntity : class
{
Task InsertEntityAsync(TEntity entity);
}
internal class Repository<TEntity> : IRepository<TEntity> where TEntity : class
{
private readonly DbContext _dbContext;
public Repository(DbContext dbContext)
{
_dbContext = dbContext;
}
public async Task InsertEntityAsync(TEntity entity)
{
await _dbContext.Set<TEntity>().AddAsync(entity);
}
}
现在在你的类库中编写一个服务集合扩展方法如下:
Now write a a service collection extension method in your class library as follows:
public static class ServiceCollectionExtensions
{
public static void RegisterYourLibrary(this IServiceCollection services, DbContext dbContext)
{
if (dbContext == null)
{
throw new ArgumentNullException(nameof(dbContext));
}
services.AddScoped<IUnitOfWork, UnitOfWork>(uow => new UnitOfWork(dbContext));
}
}
现在在您的客户端应用程序的 Startup.ConfigureServices
中,如下所示:
Now in the Startup.ConfigureServices
of your client application as follows:
public void ConfigureServices(IServiceCollection services)
{
string connectionString = Configuration.GetConnectionString("ConnectionStringName");
services.AddDbContext<AppDbContext>(option => option.UseSqlServer(connectionString));
ServiceProvider serviceProvider = services.BuildServiceProvider();
AppDbContext appDbContext = serviceProvider.GetService<AppDbContext>();
services.RegisterYourLibrary(appDbContext); // <-- Here passing the DbConext instance to the class library
.......
}
用法:
public class EmployeeController : Controller
{
private readonly IUnitOfWork _unitOfWork;
public EmployeeController(IUnitOfWork unitOfWork)
{
_unitOfWork = unitOfWork;
}
public async Task<IActionResult> Insert()
{
Employee employee = new Employee();
await _unitOfWork.Repository<Employee>().InsertEntityAsync(employee);
await _unitOfWork.SaveChangesAsync();
return View();
}
}
这篇关于如何在单独的类库 .net core 中使用 DbContext?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!