[英]Injecting Dependency in Method in ASP.NET Core
我有以下場景:我得到了一個服務ICompanyDocumentsService
,其中有一個我在Startup
類中注冊的單一實現CompanyDocumentsService
:
public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<ICompanyDocumentService, CompanyDocumentService>();
}
我在很多地方都需要這個服務,在 Constructor 中使用 DI 並不會打擾我。 但是,有一個地方我需要在方法中注入它(或者可能在屬性中會更好):
public abstract class CompanyDocumentBase
{
public abstract object GetAllProperties(Employee employee, string properties,
CompanyDocumentReferenceData documentReferenceData);
// blah, blah, lots of Formatting Methods
private CompanyDocumentService CompanyDocumentService { get; set; } // **inject service here**
public string GetFormattedEmployeeIndividualEmploymentAgreementNumber(Employee employee,
ICompanyDocumentService companyDocumentService = null) // **optional because
//inherited class doesn't need to know anything about this service, it concerns only it's result**
{
companyDocumentService = CompanyDocumentService;
var test =
companyDocumentService.GetEmloyeeIndividualEmploymentAgreementNumber(employee.Id);
return string.Empty;
}
}
有很多繼承CompanyDocumentBase
類只關心它的方法結果,如上所述,這就是為什么該參數是可選的,這就是為什么我不需要在構造函數中注入 DI,因此繼承類將不需要那個。
public class JobDescriptionCompanyDocument : CompanyDocumentBase
{
public override object GetAllProperties(Employee employee,
string properties, CompanyDocumentReferenceData documentReferenceData)
{
var document = JsonConvert.DeserializeObject<JobDescriptionModel>(properties);
document.IndividualEmploymentAgreementNumber = GetEmployeeIndividualEmploymentAgreementNumber(employee);
return document;
}
}
有什么簡單的方法可以實現這一目標嗎? 最好不需要安裝單獨的庫,如 Unity 或 Autofac。 理想的做法是以某種方式將CompanyDocumentsService
的實例直接放入該屬性中,例如:
private CompanyDocumentService CompanyDocumentService => Startup.Services.blah that instance
一種 hack 方式(我個人不推薦它)是在構建容器之后,您可以解析IHttpContextAccessor
的實例並將其設置為靜態類,例如IoC
然后你可以做private CompanyDocumentService CompanyDocumentService => IoC.HttpContextAccessor.HttpContext.RequestServices.GetService()
。
該接口是一個單例,並提供從靜態上下文對范圍服務的訪問。
請注意,您可能必須明確注冊 HttpContextAccessor: https ://docs.microsoft.com/en-us/aspnet/core/fundamentals/http-context ? view = aspnetcore-3.1
更新
我會推薦什么
如果您對對象工廠持開放態度,並改變了DocumentBase
的實例化方式,請嘗試創建一個工廠,並且每當您需要DocumentBase
的實例時,只使用工廠來創建它:
public abstract class CompanyDocumentBase
{
// Use internal so that access only limited to friendly assembly
internal CompanyDocumentService CompanyDocumentService { get; set; }
}
// Inject this class to where you need to create an instance of CompanyDocumentBase
public class CompanyDocumentFactory<T> where T : CompanyDocumentBase
{
private readonly IServiceProvider _services;
// DI contaiener has implicit IServiceProvider support, when you do this on constructor, it injects service provider of *current* scope
// If this factory is registered as singleton, you need to use IHttpContextAccessor to use request's service provider in Create method
// because your DocumentService is scoped.
public CompanyDocumentFactory(IServiceProvider services)
{
_services = services;
}
public T Create()
{
// Create an instance of document use your current method.
var instance = new T();
instance.CompanyDocumentService = _services.GetRequiredService<ICompanyDocumentService>();
return instance;
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.