假設我在 ASP.NET 6 Web 應用程式中注冊了一個作用域服務Program.cs:
services.AddScoped<MyRequestService>();
現在假設我有一些在 MVC 路由之后運行的自定義中間件:
app.UseRouting();
app.Use(async delegate (HttpContext Context, Func<Task> Next)
{
await Next(); // <-- here a controller gets instantiated based on MVC routing
// and *MIGHT* have 'MyRequestService' injected, but
// it's *NOT GUARANTEED*
// what do I put here to check if 'MyRequestService' was injected into the
// controller that was chosen by MVC?
});
現在,在中間件中呼叫之后await Next(),我想檢查MyRequestServiceMVC 選擇的控制器是否使用了它。我怎樣才能做到這一點?
我不能使用Context.RequestServices.GetRequiredService<MyRequestService>(),因為如果它尚未實體化,它只會實體化服務。我需要檢查控制器是否注入了它,而不會無意中實體化它。
uj5u.com熱心網友回復:
我不會嘗試通過反射掃描 DI 容器,而是嘗試使用HttpContext該類。它具有 和 之類的Features屬性Items。兩者都能夠在當前背景關系范圍內保存任意資料。例如,您的服務可以將具有特定鍵的條目(例如 const 字串)添加到Items字典中,其中包含值中所需的任何資料,并且在回傳后檢查Next()字典是否包含指定鍵的中間件。如果是,則使用了您的服務。
在這種情況下,使用 ASP 的默認機制,不需要反射。
uj5u.com熱心網友回復:
這就是我要做的,它沒有經過測驗,但我認為這個概念應該有效,并且在我看來它比反思更容易閱讀:
// Scoped
MyRequestService {
constructor(MyServiceMonitor monitor) {
monitor.AddResolved(this.GetType().Name);
}
}
// Scoped
MyServiceMonitor {
List<string> types;
AddResolved(string type) {
types.Add(type);
}
IsResolved(string name) {
return types.Contains(name);
}
}
// Check in the delegate
context.RequestServices.GetRequiredService<MyServiceMonitor>().IsResolved("MyRequestService");
uj5u.com熱心網友回復:
我在評論中根據 Jonesopolis 的建議使用了反射,但我沒有在控制器上使用反射,而是使用它來獲取內部依賴注入物件快取。我正在使用物件快取ResolvedServices 。 這行得通,但我不喜歡它。希望 ASP.NET 很快就會有一個公共訪問器:PropertyInfoLazy<PropertyInfo>
app.UseRouting();
var ResolvedServicesPropLoader = new Lazy<PropertyInfo>(delegate ()
{
var ProviderType = Type.GetType("Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope, Microsoft.Extensions.DependencyInjection");
if (ProviderType == null) { throw new Exception("service caching class type could not be found"); }
var TheProperty = ProviderType.GetProperty("ResolvedServices", BindingFlags.NonPublic | BindingFlags.Instance);
return TheProperty ?? throw new Exception("could not find the cached services property using reflection");
});
app.Use(async delegate (HttpContext Context, Func<Task> Next)
{
await Next();
var InjectedServices = (ICollection<object>?)((IDictionary?)ResolvedServicesPropLoader.Value.GetValue(Context.RequestServices))?.Values;
if (InjectedServices == null) { throw new Exception("cached services collection is null"); }
if (InjectedServices.Where(x => x is MyRequestService).Any())
{
Console.WriteLine("service was injected");
}
});
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/483864.html
標籤:C# 网 asp.net-mvc asp.net 核心 依赖注入
上一篇:如何創建級聯下拉選單
下一篇:資料表跳過列的配置資料
