如何對構造函數參數進行約束?
這是一個很好的做法嗎?如何在接口中對構造函數參數進行約束?
我有一個接口,我會要求記錄器組件(由統一注入)。
如何強制執行所有派生類將Logger組件(ILogger)作爲參數?
我找不到任何合適的解決方案。
我發現的唯一解決方法是在接口中放置方法Initialize (<parameters>)
。這是一種醜陋的做法,需要特殊處理。
有沒有解決這些問題的設計模式?
如何對構造函數參數進行約束?
這是一個很好的做法嗎?如何在接口中對構造函數參數進行約束?
我有一個接口,我會要求記錄器組件(由統一注入)。
如何強制執行所有派生類將Logger組件(ILogger)作爲參數?
我找不到任何合適的解決方案。
我發現的唯一解決方法是在接口中放置方法Initialize (<parameters>)
。這是一種醜陋的做法,需要特殊處理。
有沒有解決這些問題的設計模式?
您不需要約束來強制派生類具有記錄器組件。只需定義基類構造函數即可獲得一個ILogger。
public class Foo
{
public Foo (ILogger logger) { /* some implementation here */ }
}
public class Bar : Foo
{
public Bar(ILogger logger)
: base(logger)
{
// some implementation here
}
}
因爲Bar派生自Foo,所以它被迫使用帶有記錄器的構造函數。您還可以創建Foo抽象,這將強制用戶創建派生類的實例,而不是Foo本身。
當你需要定義一個接口時,不要只考慮一個C#接口。抽象類適用於這種情況。通常將抽象類看作接口(而不是C#接口)。你所要求的不能用C#接口完成,因爲它們定義了契約而不是實現。
爲什麼你會想要強迫這樣的事情?
專注於什麼是真正的契約(由接口定義),而不是像記錄這樣不重要的事情。應該以某種方式定義合同,即在不失去執行核心功能的情況下不能移除任何方法/屬性。
例如,如果你有一個接口:
interface IAdder
{
double Add(double first, double second);
}
增加是核心功能。你可以有第三個參數ILogger,但沒有它你仍然可以添加。日誌記錄是實現細節,它不應該成爲合作的一部分。
你不能在C#中使用接口的構造函數施加約束[見這裏](http://stackoverflow.com/questions/619856/interface-defining-a-constructor-signature)。 – Candide
它不像你看起來有一個'Initialize'方法那麼醜,因爲它接受這些組件所需要的。無論如何,這是解決這個問題的標準方法。 – Servy