首页 文章

在同一个Asp.Net Core 2解决方案中将DbContext注入到类库项目中

提问于
浏览
1

曾经相对容易的事情已不再如此 . 在我搜索过的几十次中,我很少找到这种情况的答案,在大多数项目结构中,我无法相信这种情况 .

我有标准的Core 2.0 Web应用程序,目前为简单起见,还有一个Infrastructure项目和一个单元测试项目 . 我很清楚如何完成测试场景,因为测试项目没有运行asp.net,我有一个关于如何完成它的精彩视频教程 .

问题在于在我的基础架构项目中访问DbContext . (.Net Core类库)

DbContext在Startup中设置得非常好

var connString = Configuration.GetSection("ApplicationConfiguration:ConnectionStrings:DefaultConnection").Value;
        services.AddDbContext<ApplicationDbContext>(options =>
            options.UseSqlServer(connString));

在控制器中我可以访问它

private ApplicationDbContext _context;
private IConfiguration Configuration { get; set; }

public HomeController(IConfiguration configuration, ApplicationDbContext context)
{
    _context = context;
    Configuration = configuration;
}

public IActionResult Index()
{
     // gets users from the DI injected context in the controller
    var users = _context.AppUsers.ToList();

    // if GetUsers is defined statically, this doesn't work because the injected context is always null
    //var diUsers = DatabaseService.GetUsers():

    // making it non-static and newing it up works, but defeats the purpose because you are passing the context, asp.net is not injecting it
    var ds = new DatabaseService(_context);
    var diUsers = ds.GetUsers();

    var svm = SettingsViewModel();

    return View(svm);
}

DatabaseService

private ApplicationDbContext _context;
//this is the constructor for DatabaseService class
public DatabaseService(ApplicationDbContext context)
{
    _context = context;
}

public List<ApplicationUser> GetUsers()
{
    var users = _context.AppUsers.ToList();
    return users;
}

是的,我知道我应该使用存储库,一旦我弄清楚了这一点,我就会知道 . 如何在Infrastructure项目中设置我的类,以便在Startup中创建注入的DbContext,而不必将其作为参数传递 .

附录:

使用Nkosi提供的答案,我可以在控制器中注入数据服务并使用它 .

但是如果我有一个单独的基础设施项目(Asp.net核心2类库),它实现了我的存储库和UoW

public class GenericRepository<T> : IRepository<T> where T : class
{
    public GenericRepository()
    {

    }
    //rest of code removed
}

如何在那里注入DbContext?我是否需要创建一个接口IDbContext来包装DbContext,并在启动时注册它?

1 回答

  • 1

    假设您有以下服务

    public interface IDatabaseService {
        List<ApplicationUser> GetUsers();
        //...
    }
    
    public class DatabaseService : IDatabaseService {
    
        public DatabaseService(ApplicationDbContext context) {
            //...code removed for brevity
        }
    
        //...code removed for brevity
    }
    

    该服务明确依赖于 ApplicationDbContext ,它将在从服务容器解析实现时注入 .

    Startup.ConfigureServices 注册服务

    var connString = Configuration.GetSection("ApplicationConfiguration:ConnectionStrings:DefaultConnection").Value;
    services.AddDbContext<ApplicationDbContext>(options =>
            options.UseSqlServer(connString));
    services.AddScoped<IDatabaseService, DatabaseService>();
    

    并重构控制器以明确依赖于服务

    private IDatabaseService ds;
    private IConfiguration Configuration { get; set; }
    
    public HomeController(IConfiguration configuration, IDatabaseService ds) {
        this.ds = ds;
        Configuration = configuration;
    }
    
    public IActionResult Index() {
        var diUsers = ds.GetUsers();
    
        var svm = SettingsViewModel();
    
        return View(svm);
    }
    

相关问题