我正在尝试将依赖项注入到我的 Django 视图(控制器?)中。这是一些背景知识。
通常情况下,urls.py
文件是处理路由的。通常是这样的:
urlpatterns = [
path("", views.get_all_posts, name="get_all_posts"),
path("<int:post_id>", views.get_post, name="get_post"),
path("create", views.create_post, name="create_post"),
]
问题在于,一旦你到达create_post
例如,您可能依赖于创建帖子的服务:
# views.py
...
def create_post(self):
svc = PostCreationService()
svc.create_post()
这种模式很难测试。虽然我知道 python 测试库有工具来模拟此类事情,但我宁愿将依赖项注入视图中。这就是我的想法。
具有静态方法的控制器类,export(deps)
它接受依赖项列表并返回 url 模式对象列表:
class ApiController(object):
@staticmethod
def export(**deps):
ctrl = ApiController(**deps)
return [
path("", ctrl.get_all_posts, name="get_all_posts"),
path("<int:post_id>", ctrl.get_post, name="get_post"),
path("create", ctrl.create_post, name="create_post"),
]
def __init__(self, **deps):
self.deps = deps
def get_all_posts():
pass
...
这看起来很笨拙,但我不知道有任何其他方法可以完成我想做的事情。控制器需要返回 url 模式列表,并且还需要接收依赖项列表。使用上述技术,我可以这样做urls.py
:
urlpatterns = ApiController.export(foo_service=(lambda x: x))
我现在可以免费使用foo_service
在任何方法中ApiController
.
Note:
一种替代方法是让构造函数返回 url 列表,但我不认为这是对此的巨大改进。事实上,我觉得这更令人困惑,因为类构造函数将返回一个列表而不是类的实例。
Note 2:
我知道 python 有用于模拟类成员的模拟工具。请不要建议使用它们。我想使用 DI 作为控制和管理依赖项的方式。
关于最好的方法是什么有什么想法吗?