[英]How can I use/inject a service in a “normal” c# class like in Blazor @inject ClassName classObject
[英]How to determine to use trait to 'with' or class to 'inject'?
在編寫scala代碼時,我很困惑地選擇一個trait
或class
。
起初,我有一個控制器, with
幾個特點:
class MyController extends Controller
with TransactionSupport
with JsonConverterSupport
with LoggerSupport
在這些特性中,我定義了一些可以直接在MyController
使用的方法和字段。
但我的朋友說:當你extends
或with
特質時,它應該be a
特質。
看看MyController
,它是一個Controller
,但它不是一個TransactionSupport
,不是一個JsonConverterSupport
,不是一個LoggerSupport
,所以它不應該with
它們一起使用。
所以代碼變成:
class MyController(tranSupport: TransactionSupport,
jsonConverter: JsonConverterSupport,
loggerSupport: LoggerSupport) extends Controller
但我對這段代碼感覺不太好,這看起來很奇怪。
我看到trait
在scala代碼中大量使用,我什么時候應該使用它或者使用類來注入?
我會推薦你接口應該是形容詞 。 雖然一些特征可能扮演一個類的一部分(因此,是名詞並尊重“是一個”關系),但當用作mixin時,它們往往會扮演界面的一部分。
作為一個“形容詞”,該特征將為他們所擴展的任何內容添加一個合格的屬性。 例如,它們可能是Comparable
或Serializable
。
找到一個適合的形容詞可能有點難度 - 你會用什么形容詞來表示LoggerSupport
? - 所以不要覺得過分受到限制。 請注意,特質是完全錯誤的,因為它必然是一種“是一種”的關系。
不過,我會盡量避免使用特征來代替“has-a”關系。
我的意見是,它不一定to be
它。 混合是一種與繼承不同的概念。 即使在語法上它是相同的,但它並不意味着相同。 混合的典型用例就像你寫的那樣記錄。 這並不意味着如果您的服務類混合了Logging
特性, it is
一個記錄器。 這只是如何將功能組合到工作對象中的另一種方式。
奧德斯基建議,如果你不確定,你可以使用trait
因為它們更靈活。 如果需要,您可以在將來將trait
更改為class
。
有時當我覺得混合特性看起來不好時,我會使用這樣的模塊模式:
trait JsonConverterModule {
protected def jsonConverter: JsonConverter
protected trait JsonConverter {
def convert(in: Json): Json
}
}
class MyController extends Controller with JsonConverterModule {
private doSmth = jsonConverter.convert(...)
}
在這種情況下,MyController看起來更像是一個Controller,所有與Json相關的東西都隱藏在MyController'client'中
你的第一個特征示例是“蛋糕模式”,第二個例子是“構造函數注入”。 兩者都是在Scala中進行依賴注入的完全有效的方法。 蛋糕模式功能強大,你可以注入類型成員,不同的特性可以很容易地相互通信(我們不必創建單獨的對象並將它們傳遞給每個其他對象,通常需要setter注入而不是簡單的構造函數注入),但是,必須在編譯時實現類型,並且必須為每個特征組合實現單獨的類。 構造函數注入允許您在運行時構建對象,並且可以針對大量組合進行更好的擴展。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.