使用 .NETCore 進行 DAL 和連接字元串的依賴注入
我是 .NETCore 的 DI 模式的新手,我無法將連接字元串連接到我的 DAL。
我通過接受的答案和後續評論遵循了該執行緒中給出的建議。
這是我的基類
public class BaseRepository : IRepository<IDataModel> { private readonly IConfiguration config; public BaseRepository(IConfiguration config) { this.config = config; } public string GetSQLConnectionString() { return config["Data:DefaultConnetion:ConnectionString"]; }這是繼承基類的儲存庫類的片段
public class PrivacyLevelRepository : BaseRepository, IRepository<PrivacyLevelDM> { public PrivacyLevelRepository(IConfiguration config) : base(config) { } public void Add(PrivacyLevelDM dataModel) { ... } }這是在我的 startup.cs
public void ConfigureServices(IServiceCollection services) { // Add framework services. services.AddMvc(); services.AddScoped<IRepository<IDataModel>>(c => new BaseRepository(Configuration)); }但是,在我的服務層中,儲存庫類的實例化仍然要求將 (IConfiguration config) 作為參數傳遞。
PrivacyLevelRepository repo = new PrivacyLevelRepository();如何將 IConfiguration 直接載入到我的 DAL,而不必從 Controller > BLL > DAL 傳遞它。這似乎效率極低,而且不正確。因為 DAL 應該確定對象的連接,而不是控制器或服務層。他們應該不知道數據源,不是嗎?
我認為這很簡單,我只是在 DI/IoC 範式中看不到,但我無法弄清楚。
編輯:我沒有使用實體框架,而是自定義數據層。
感謝任何幫助。
您可以使用配置框架遵循選項模式。這允許您定義一個自定義類型來保存您的配置設置(靜態類型),同時僅限於您的實際相關配置。
你可以像這樣使用它:
public void ConfigureServices(IServiceCollection services) { // register the `Data:DefaultConnection` configuration section as // a configuration for the `DatabaseOptions` type services.Configure<DatabaseOptions>(Configuration.GetSection("Data:DefaultConnection")); // register your database repository // note that we don’t use a custom factory where we create the object ourselves services.AddScoped<IRepository<IDataModel>, BaseRepository>(); }這假設一個
DatabaseOptions像這樣的類型:public class DatabaseOptions { public string ConnectionString { get; set; } }然後,您可以將其
DatabaseOptions註入您的BaseRepository:public class BaseRepository { private readonly DatabaseOptions _options; public BaseRepository(IOptions<DatabaseOptions> databaseOptions) { _options = databaseOptions.Value; } }當然,如果你有 that 的子類型
BaseRepository,你也需要註冊它們並將選項傳遞給基類:// register the repository as well in the `ConfigureServices` method services.AddScoped<PrivacyLevelRepository>();public class PrivacyLevelRepository : BaseRepository, IRepository<PrivacyLevelDM> { public PrivacyLevelRepository(IOptions<DatabaseOptions> databaseOptions) : base(databaseOptions) { } }我像往常一樣實例化和使用 repo。我不確定如何使用我沒有實例化的類。我如何讓這個對象知道它取決於
PrivacyLevelRepository?PrivacyLevelRepository repo = new PrivacyLevelRepository(); returnValue = repo.GetAllByDomainID(DomainID).ToList(); return returnValue;您似乎還不了解依賴注入背後的想法。依賴注入及其基本原理控制反轉簡單地說是避免使用
new創建對象。您不是主動依賴實現(在您的範例中為PrivacyLevelRepository),而是放棄了責任,只依賴外部系統為您提供所需的依賴項。因此,您不是創建一個新的
PrivacyLevelRepository,而是注入一個由其他地方創建的實例。這會在您的依賴項的實現上鬆散耦合。一個非常實際的例子是如何PrivacyLevelRepository依賴IOptions<DatabaseOptions>. 作為該儲存庫的消費者,您不需要關心如何獲取這樣的對象來創建儲存庫實例。您甚至不需要知道如何首先創建儲存庫實例。因此,您的使用者
PrivacyLevelRepository應該遵循與儲存庫本身相同的想法:儲存庫不知道如何獲取這些數據庫選項;它只依賴於構造實體來傳遞這樣的對象。你的消費者,我假設一個控制器,應該做同樣的事情:public class MyController { private readonly PrivacyLevelRepository _privacyLevelRepository; public MyController(PrivacyLevelRepository privacyLevelRepository) { // instead of *creating* a repository, we just expect to get one _privacyLevelRepository = privacyLevelRepository; } public IActionResult SomeRoute() { var domainId = "whatever"; var data = _privacyLevelRepository.GetAllByDomainID(domainId).ToList(); return View(data); } }當然,必須在某些時候創建依賴項。但是,如果您完全接受依賴注入(ASP.NET Core 不僅非常容易,而且還主動要求您這樣做才能完全工作),那麼您就不需要關心這部分了。您只需在
ConfigureServices方法中註冊類型,然後期望依賴項在您需要的地方得到滿足。有關更多資訊,您絕對應該查看文件的依賴注入章節。