簡體   English   中英

Autofac中注冊和解析不同TypeOf的不同參數構造函數

[英]Registering and Resolving Different Parameter Constructors with different TypeOf in Autofac

我有一個 class 有 2 個構造函數,在構造函數中有 2 個不同類型的參數,這很好用,直到我有一個構造函數,但是一旦我創建另一個構造函數並嘗試解決它,autofac 崩潰並說使用構造函數配置指定構造函數,我嘗試在 DI 中注冊構造函數,但第一個注冊覆蓋了第二個

builder.RegisterType<DeviceMasterPageViewModel>().UsingConstructor(typeof(DeviceListModel));
builder.RegisterType<DeviceMasterPageViewModel>().UsingConstructor(typeof(int));

這是我的 class 和 2 個構造器

public DeviceMasterPageViewModel(DeviceListModel scannendDevice)
    {}
 public DeviceMasterPageViewModel(int selectedDeviceID)
    {}

我不明白我應該如何在 DI 中注冊這個 class 以便當我傳遞特定類型的參數時,應該調用指定類型的構造函數

您只能通過一種方式向 Autofac 注冊組件。 最后注冊獲勝。 這就是為什么當您嘗試注冊兩次時它不起作用的原因。

通常,您嘗試做的事情與 DI 並不真正兼容。 DI 真的希望在您的 object 上有一個構造函數,僅此而已。 此外,您建議的其中一個構造函數中有一個原始類型( int ),這對於 DI 也不是很好。

如果 DI 允許兩個構造函數......它如何選擇? 假設在解析上下文int參數DeviceListModel參數都可用。 哪個構造函數是正確的?

如果您在構造函數中使用int ......因為您實際上只能注冊給定System.Type的一個注冊,這意味着您擁有的任何int int 那正確嗎?

所以,說了這么多,假設你仍然真的希望這發生。 您將不得不編寫自己的一些邏輯。

該邏輯的一部分需要知道您期望構造函數參數來自哪里。 它們是您正在解決的應該已經在容器中注冊的東西嗎? 或者它們是你要傳遞的東西?

也就是說,您有兩個基本場景:

# All the stuff the DMPVM needs is _registered_
var b = new ContainerBuilder();
b.Register(3).As<int>();
b.RegisterType<DeviceListModel>().AsSelf();
b.RegisterType<DeviceMasterPageViewModel>().AsSelf();
var c = b.Build();
var d = c.Resolve<DeviceMasterPageViewModel>();

或者

# You plan on _passing in_ the values
var b = new ContainerBuilder();
b.RegisterType<DeviceMasterPageViewModel>().AsSelf();
var c = b.Build();
var d = c.Resolve<DeviceMasterPageViewModel>(new TypedParameter(typeof(int), 3));

(這是評論中提出的問題的症結所在。了解這一點對於您將編寫的自定義邏輯類型很重要。)

如果您假設所有內容都將被注冊,那么您可能需要編寫自己的IConstructorSelector Autofac 附帶了兩種,一種與最可用的參數匹配,另一種與特定的構造函數簽名匹配。 然后,您可以在注冊期間提供您的構造函數選擇器。

如何准確地寫這將取決於你。 我認為這不是一個好主意,它會有很多警告,比如如果你有很長的生命周期來解決組件會發生什么; 以及它對應用性能有何影響; 等等。 這完全取決於你。

如果你傳遞參數,它會更容易一些。 您可以注冊一個 lambda,而不是編寫構造函數選擇器。 查找參數並根據需要使用它們。 這是記錄在案的。

它可能是這樣的:

b.Register((ctx, plist) => {
  var intParam = plist
    .OfType<TypedParameter>()
    .Where(p => p.Type == typeof(int))
    .FirstOrDefault();
  if(intParam != null) {
    return new DeviceMasterPageViewModel((int)intParam.Value);
  }

  // int param isn't found, do a similar search for the
  // DeviceListModel parameter.
}).As<DeviceMasterPageViewModel>();

如您所見,您可以根據傳入的參數在此處執行一些動態工廠樣式邏輯。

但是,同樣,如果你完全避免這種情況,你的生活會容易得多。

暫無
暫無

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

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