如何使用静态方法进行依赖注入?
想象一下,有一个带有实例 Load()
方法的 Customer
类。
当调用 Load()
方法时,它会通过 GetAll()
检索订单详细信息,例如
var orders = Order.GetAll(customerId, ...);
GetAll()
是 Order
类的静态方法,并且输入参数是在 Customer
类中定义的字段。
如您所见,Order
是 Customer
类的依赖项,但是,我不能只创建一个 IOrder
并将其注入其中接口不能有静态方法。
因此,问题是如何在这个例子中引入依赖注入?
我不想将 GetAll()
设为实例方法,因为它是静态方法并且需要保持这种状态。
例如,我在设计中使用了实用程序类,其中大多数只包含静态方法。
Imagine there is a Customer
class with an instance Load()
method.
When the Load()
method is called, it retrieves order details by e.g.
var orders = Order.GetAll(customerId, ...);
GetAll()
is a static method of the Order
class and the input parameters are fields defined in the Customer
class.
As you can see, Order
is a dependency of the Customer
class, however, I can't just create an IOrder
and inject it there as interfaces can't have static methods.
Therefore, the question is how could I introduce dependency injection in this example?
I don't want to make GetAll()
an instance method since it's a static method and need to keep it that way.
For example, I have used utility classes in my design, most of which just contain static methods.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
如果您必须保留静态方法,我会将静态调用包装在 Repository 对象中。
像这样:
现在您将此存储库注入到您的
Customer
类中。(我假设您这样做是为了在运行时注入假 IOrder 以进行测试。我应该说,一般来说,静态方法是测试的严重障碍。)
If you must keep the static method, I would wrap the static calls in a Repository object.
Like this:
Now you inject this repository into your
Customer
class.(I'm assuming you're doing this so you can inject fake IOrders at runtime for testing purposes. I should say that in general, static methods are a serious obstacle to testing.)
鉴于获取订单的聚合根是您的客户模型,我强烈建议您创建一个客户存储库并将其注入到任何需要它的服务中。
这是一个例子:
Seeing as your aggregate root for fetching orders is your customer model I would strongly advise you create a customer repository and inject that to whatever service requires it.
Here is an example:
函数指针注入
TLDR:
将函数指针注入到
Customer
类中。该函数指针的值在生产中可以是Order.GetAll
,在测试中可以是MockOrder.GetAll
。示例:
依赖关系(我们依赖的有问题的静态函数):
我们的依赖类(依赖于静态函数):
生产客户端类(执行依赖注入 em>):
测试客户端类(单元测试如何注入虚假依赖项):
讨论:
如何实际注入“函数指针”将取决于您的语言中可用的语法和功能。这里我只讲一个大概的概念。
这并不是一个很好的解决方案。如果您可以将
GetAll
更改为实例方法(也许通过引入OrdersLoader
对象,或使用 Paul Phillips 的答案),可能会更容易。但如果你真的想将其保留为静态函数,那么这个解决方案将起作用。Function Pointer Injection
TLDR:
Inject a function pointer into the
Customer
class. The value of this function pointer can beOrder.GetAll
in production, andMockOrder.GetAll
in tests.EXAMPLE:
The dependency (problematic static function we depend on):
Our dependent class (depends on static function):
Production client class (performs the dependency injection):
Testing client class (how unit test can inject a fake dependency):
DISCUSSION:
How you actually inject the "function pointer" will depend on the syntax and features available in your language. Here I'm just talking about the general concept.
This isn't exactly a pretty solution. It would probably be easier if you can change
GetAll
to be an instance method (perhaps by introducing anOrdersLoader
object, or by using Paul Phillips' answer). But if you really want to keep it as a static function, then this solution will work.