[英]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.