簡體   English   中英

兩個 ASP.NET 核心項目之間的依賴注入

[英]Dependency injection between two ASP.NET Core projects

我目前正在使用 ASP.NET Core 開發 web 應用程序,並使用 Entity Framework Core 處理數據庫。 我的 VS 解決方案中有兩個項目; WebApp(主應用程序)和 DatabaseHandler(EF Core 處理程序)。 我使用 Pomelo package 安裝了 Entity Framework Core,因為我使用的是 MySQL 數據庫。

我一直在關注 Microsoft 文檔來設置 EF Core、連接字符串和所有這些,它工作正常。 我能夠對數據庫進行遷移、更新和處理。 但是,我不確定我是否正確執行此操作,因為最新的 EF Core 教程使用依賴注入並且我不熟悉它。

現在我將 DbContext object 作為 WebApp 的參數傳遞給 DatabaseHandler,因為我希望所有與數據庫相關的東西只存在於 DatabaseHandler 中。 這可行,但是否可以從另一個項目調用函數並共享 DbContext object 而無需將其作為參數傳遞? 我可能沒有很好地解釋它,我希望我的代碼能更好地解釋它。

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();
}

WebApp/HomeController.cs:
這是我從 DatabaseHandler 項目中調用 GetAllChallenges() function 的地方,我還將 DataContext object 作為參數傳遞。 這是我要避免的!

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);
    }
}

數據庫處理程序/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();
    }
}

DatabaseHandler/HandleChallenges.cs:
這是我擁有所有數據庫功能的地方。 結果將返回到 WebApp 項目中的 controller。

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

我已經研究過依賴注入,但我不確定如何在兩個項目之間使用它。 有沒有更簡單的方法來實現這一點,也許根本不使用 DI? 只要我不需要每次需要從 DatabaseHandler 調用 function 時都不需要將 DataContext object 作為參數傳遞,我就很滿意。

有人可以幫我理解嗎? 提前非常感謝!

您可以使用我已經多次使用過的選項模式。 盡管您使用了數據庫,但它工作得很好。 由於依賴注入,您可以從多個項目中訪問。 閱讀有關選項模式的文檔( https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/options?view=aspnetcore-3.1 )很有用,但我也會為您提供我自己的示例:

  1. 首先創建 model 來存儲連接字符串、dbName 等。記住將其添加到主項目之外的庫中(例如 Web Api):

     public class NameOfYourProject_ApiDbSettings: IIMTTApiDbSettings { public NameOfYourProject_ApiDbSettings() { } public string CollectionName { get; set; } public string ConnectionString { get; set; } public string DatabaseName { get; set; } } public interface I_NameOfYourProject_ApiDbSettings { string CollectionName { get; set; } string ConnectionString { get; set; } string DatabaseName { get; set; } }
  2. 其次,您使其可用於所有項目:

     services.Configure<NameOfYourProjectApiDbSettings>(options => { options.ConnectionString = Configuration.GetSection("NameOfYourProjectDbSettings:ConnectionString").Value; options.DatabaseName = Configuration.GetSection("NameOfYourProjectDbSettings:DatabaseName").Value; });
  3. 然后你可以在多個項目中使用它。 (請記住為您添加參考 model -> 第 1 點。我將 model 始終與存儲庫一起保存)我會給你我使用 MongoDb 的示例:

     private readonly IMongoDatabase _database = null; public SomeObjectContext(IOptions<IMyProjectDbSettings> settings) { var client = new MongoClient(settings.Value.ConnectionString); if (client.= null) _database = client.GetDatabase(settings.Value;DatabaseName). } public IMongoCollection<MyModel> MyModels { get { return _database;GetCollection<MyModel>("MyModels"); } }

您需要從 class 中提取一個接口(注意該方法不再是靜態的)並為上下文添加一個構造函數:

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;
    }
}

然后將其注冊為服務:

 services.AddScoped<IHandleChallenges, HandleChallenges>();
 

您的 controller 現在在其構造函數中接收class 而不是上下文:

private IHandleChallenges _challengeHandler;
public HomeController(ILogger<HomeController> logger, IHandleChallenges challengeHandler)
{
    _logger = logger;
    _challengeHandler = challengeHandler;
}

並從動作中調用它:

public IActionResult Challenges()
{
    List<Challenge> ChallengesList = _challengeHandler.GetAllChallenges();
    return View(ChallengesList);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM