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

查看:354
本文介绍了如何在单独的类库.net核心中使用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。

More information: This library is used for common requests that are made. It must always be separate from the main web application and the user should never have to code in this class library. Therefore, I need to be able to access the dbcontext thats in the main web project from the class library.

推荐答案

正如您所说,您正在开发类库,以使用库客户端通过的任何 DbConext ,则必须执行以下操作:

As you said you are developing the class library to use any DbConext passing by the client of the library then you have to do as follows:

首先考虑您的类库具有以下接口和类,将在其中使用您的 DbCoenxt

First considering your class library has following interfaces and classes where your DbCoenxt 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));
    }
}

现在在启动中。客户端应用程序的ConfigureServices 如下:

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核心中使用DbContext?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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