两个 ASP.NET Core 项目之间的依赖注入

Sir*_*jad 5 c# asp.net entity-framework-core .net-core asp.net-core

我目前正在使用 ASP.NET Core 开发一个 Web 应用程序,并使用 Entity Framework Core 处理数据库。我的 VS 解决方案中有两个项目;WebApp(主应用程序)和 DatabaseHandler(EF Core 处理程序)。我已经使用 Pomelo 包安装了 Entity Framework Core,因为我使用的是 MySQL 数据库。

我一直按照 Microsoft 文档来设置 EF Core、连接字符串等,并且运行良好。我能够进行迁移、更新以及对数据库进行操作。然而,我不确定我是否做得正确,因为最新的 EF Core 教程使用依赖注入,而我对此并不熟悉。

现在,我将 DbContext 对象作为参数从 WebApp 传递到 DatabaseHandler,因为我希望所有与数据库相关的内容仅存在于 DatabaseHandler 中。这是可行的,但是是否可以从另一个项目调用函数并共享 DbContext 对象而不将其作为参数传递?我可能没有很好地解释它,我希望我的代码能更好地解释它。

WebApp/Startup.cs:
这是我从 appsettings.json 加载连接字符串的位置。

public Startup(IConfiguration configuration)
{
    Configuration = configuration;
}

public IConfiguration Configuration { get; }

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContextPool<DataContext>(
        options => options.UseMySql(Configuration.GetConnectionString("DefaultConnection")
    ));

    services.AddRouting(options => options.LowercaseUrls = true);
    services.AddControllersWithViews();
}
Run Code Online (Sandbox Code Playgroud)

WebApp/HomeController.cs:
这是我从 DatabaseHandler 项目调用 GetAllChallenges() 函数的地方,并且还将 DataContext 对象作为参数传递。这就是我想避免的!

public class HomeController : Controller
{
    private readonly ILogger<HomeController> _logger;
    private readonly DataContext db;

    public HomeController(ILogger<HomeController> logger, DataContext _db)
    {
        _logger = logger;
        db = _db;
    }

    public IActionResult Challenges()
    {
        List<Challenge> ChallengesList = DatabaseHandler.HandleChallenges.GetAllChallenges(db);
        return View(ChallengesList);
    }
}
Run Code Online (Sandbox Code Playgroud)

DatabaseHandler/DataContext.cs:
这是我初始化实体类等的地方。

public class DataContext : DbContext
{
    public DataContext(DbContextOptions<DataContext> options) : base(options) { }
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { }

    // Tables
    public DbSet<User> Users { get; set; }
    public DbSet<Challenge> Challenges { get; set; }

    // Data seeding
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Seed();
    }
}
Run Code Online (Sandbox Code Playgroud)

DatabaseHandler/HandleChallenges.cs:
这是我拥有所有数据库函数的地方。结果将返回到 WebApp 项目内的控制器。

public class HandleChallenges
{
    public static List<Challenge> GetAllChallenges(DataContext db)
    {
        var Data = db.Challenges;
        List<Challenge> ChallengesList = Data.ToList();
        return ChallengesList;
    }
}
Run Code Online (Sandbox Code Playgroud)

我研究过依赖注入,但我不确定如何在两个项目之间使用它。有没有一种不太复杂的方法来实现这一点,也许根本不使用 DI?只要我不需要每次需要从 DatabaseHandler 调用函数时都将 DataContext 对象作为参数传递,我就很满意了。

有人可以帮我理解吗?预先非常感谢!

stu*_*rtd 1

您需要从类中提取一个接口(注意该方法不再是静态的)并为上下文添加一个构造函数:

public interface IHandleChallenges
{
    List<Challenge> GetAllChallenges();
}

public class HandleChallenges : IHandleChallenges
{
    public HandleChallenges(DataContext context)
    {
        db = context;
    }
    
    private DataContext db;
    
    public List<Challenge> GetAllChallenges()
    {
        var Data = db.Challenges;
        List<Challenge> ChallengesList = Data.ToList();
        return ChallengesList;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后将其注册为服务:

 services.AddScoped<IHandleChallenges, HandleChallenges>();
 
Run Code Online (Sandbox Code Playgroud)

您的控制器现在在其构造函数而不是上下文中接收此类:

 services.AddScoped<IHandleChallenges, HandleChallenges>();
 
Run Code Online (Sandbox Code Playgroud)

并从操作中调用它:

private IHandleChallenges _challengeHandler;
public HomeController(ILogger<HomeController> logger, IHandleChallenges challengeHandler)
{
    _logger = logger;
    _challengeHandler = challengeHandler;
}
Run Code Online (Sandbox Code Playgroud)