簡體   English   中英

構造函數中的ASP.NET Core選項依賴項

[英]ASP.NET Core option dependency in constructor

我正在使用ASP.NET Core,並且嘗試創建一個具有可選參數的可解析類:

public class Foo
{
     public Foo() : this(null)
     {}

     public Foo(IValidator<FooEntity> validator)
     {
     }
}

我為該對象創建了兩個構造函數,因此,如果未找到依賴項,我將假定它會退回到默認構造函數。

但是,當我運行我的應用程序時,會出現此錯誤

附加信息:嘗試激活“ Foo”時,無法解析類型為“ FluentValidation.IValidator`1 [FooEntity]”的服務

我知道可能有一種方法可以手動解決Foo對象的構造。 但是我不希望這樣做,因為我必須為我創建的沒有驗證器的每個類都這樣做。

沒有人知道如何將ASP.NET Core DI配置為在找不到依賴項時回退到其他構造函數嗎?

編輯

抱歉,我之前應該更清楚一點。

我實際上是在CRUD服務的基類中引用這個Foo類,該類將反復使用。

我正在尋找一種通用解決方案,該解決方案不需要我配置每次創建的每個服務。

因此,使用lambda來解決此問題不是一種選擇,空對象模式似乎是可行的,但我無法理解如何編寫通用的模式,而不必為每個服務進行配置

我認為容器的一般行為是使用最多的參數來解析構造函數。

基本上, AddTransient作用如下:

services.AddTransient<Foo>();
//equals to:
services.AddTransient<Foo>(c=> new Foo(c.GetService<IValidator<FooEntity>()));

因此,您可以這樣自己注冊:

services.AddTransient<Foo>(c=> new Foo());

此時,在啟動類中,您應該知道IValidator<FooEntity>是否已注冊。 或者,如果您使用反射,則將此邏輯添加到反射代碼中。

區別

這兩個選項之間的區別在於,第一個選項是在啟動時創建用於解析類的lambda function +如果更改構造函數,則無需在其他地方更改代碼。

如果您自己創建lambda,則該lambda是在構建時編譯的,因此從理論上講,啟動速度應該更快(我尚未對此進行測試)。

偉大的心態

最好的心態是擁有您正在使用的庫。 在Visual Studio / Resharper中,您可以反編譯源代碼,或者現在可以在github上找到存儲庫。

在這里,您可以看到源代碼,可以看到如何將services參數“編譯”到IServiceProvider(請參閱BuildServiceProvider()方法,它將為您提供很多見識。)

還要看:

做到這一點的最好方法是,(抱歉偽代碼,但我手邊沒有編輯器)。

getTypes()
    .Where(x=> x.EndsWith("Entity") //lets get some types by logic
    .Select(x=> typeof(IValidator<>).MakeGeneric(x)) //turn IValidator into IValidator<T>
    .Where(x=> !services.IsRegistered(x))
    .Each(x=> services.Add(x, c=> null)) //register value null for IValidator<T> 

您需要先注冊 IValidator<T>

  var services = new Microsoft.Extensions.DependencyInjection.ServiceCollection();
  services.AddTransient<IValidator<FooEntity>, RealValidator<FooEntity>>();
  services.AddTransient<Foo>();

  var serviceProvider = services.BuildServiceProvider();
  var validator = serviceProvider.GetService<IValidator<FooEntity>>();
  var foo = serviceProvider.GetService<Foo>();

  Assert.NotNull(validator);
  Assert.NotNull(foo);

暫無
暫無

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

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