如何在单独的类库 .net core 中使用 DbContext? [英] How to use DbContext in separate class library .net core?

查看:38
本文介绍了如何在单独的类库 .net core 中使用 DbContext?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试从类库中的 .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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆