自动加载

未匹配的标注
本文档最新版为 4.0,旧版本可能放弃维护,推荐阅读最新版!

自动加载

简介

Masonite 内置的 服务容器 可以让您将对象添加到容器中并在控制器或其他类中自动解析它们。这个优秀的功能也使得 Masonite 尤为强大。通过创建 服务提供者 能简单明了地将类加载到容器中并与容器进行交互。

使用 Masonite 2,借助内置的自动加载器,能更轻松地将类加载到容器中。

配置

配置自动加载的变量位于 config / application.py 文件中,该文件包含一个目录列表:

AUTOLOAD = [
    'app',
]

默认情况下,Masonite 将自动加载 app 目录中的所有类,一般来说,该目录中包含了所有的应用模型。

运行方式

Masonite 会遍历所有上述文件中列举出的文件目录并将其转换成模块。例如,若给定的目录为 app/models ,它将被自动转换成 app.models 并获取该模块,通过检查遍历整个模块,解析出所有引入或预先定义的类。

若代码如下所示:

from orator.orm import belongs_to
from config.database import Model

class User(Model):
    pass

自动加载器需要获取三个类:belongs_toModelUser。随后自动加载器将检查需获取的类的模块是否包含在自动加载的范围内。

换句话说,上述类的模块分别是:orator.ormconfig.databaseapp。而我们仅自动加载了 app 模块,因此只有 app.User 会被绑定到容器中,绑定关系为类名 User 和对应的对象 <class app.User.User>

所有这些自动加载都是在服务器首次启动时但在 WSGI server 准备开始接受请求之前完成的,因此不会对性能造成任何影响。

用法

由于 app 目录是自动加载的,并且 User 模型在该目录中, 因此 User 模型将在服务器启动时加载到容器中。

服务容器中的所有绑定都将以对象的名称作为键,并以实际的对象作为值。因此,所以 User 模型将以如下方式访问:

app/http/controllers/YourController.py

from app.User import User

def show(self, user: User):
    user.find(1)

除非您的特定用例需要,否则没有理由将模型添加到容器中,但这只是一个示例。

其它目录

您不必将模型保存在 app 目录中。 可以将它们随意移动到任何地方,但是默认情况下它们不会自动加载到应用程序目录之外。为了自动加载其他目录,我们可以将它们添加到 AUTOLOAD 变量中。

例如,如果我们有一个应用目录结构,像这样:

app/
  http/
  providers/
  models/
    Blog.py
    Author.py
  User.py

然后,我们可以像这样编辑 AUTOLOAD 变量:

AUTOLOAD = [
    'app',
    'app/models'
]

然后能够做到:

app/http/controllers/YourController.py

from app.User import User
from app.Blog import Blog
from app.Author import Author

def show(self, user: User, blog: Blog, author: Author):
    user.find(1)
    blog.find(1)
    author.find(1)

由于该容器可用作 IOC 容器, 因此另一个用例是,如果第三方库需要一些模型来进行操作,然后将其绑定回该容器中。 这种类型的库的一个例子是需要更改模型方法,以便捕获查询操作并将它们发送到 dashboard 或 report。

例外

Autoload 类会引发一些异常,因此您应该特别要注意下,以免出现问题。

无效的自动加载路径

如果您某个自动加载的路径是以 / 结尾(比如下面代码列表中的第一个元素),会引发异常:

AUTOLOAD = [
    'app/',
    'app/models'
]

注意路径现在是 app/ 而不是 app 。这将在服务器启动时引发异常。

自动覆盖

当其中一个类会覆盖搜索路径之外的已经在容器中绑定的类时,会发生异常。搜索路径就是 您在 AUTOLOAD 常亮中指定的目录。

例如,您有一个模型叫 Request ,结构如下:

app/
  http/
  providers/
  User.py
  Request.py
bootstrap/
...

这样,您的程序将会覆盖绑定在 Masonite 上的 Request 类而引发异常。
当 Masonite 自动加载这些类的时候,它会探测到 Request 键已经绑定到了容器中,然后检测容器中的 Request 对象是否在搜索的路径内。换句话说,它会检查您自动加载的当前模块的 Request 类。
如果对象在您自动加载的模块之外,它将抛出异常。因为容器中的 Request 键是 <class masonite.request.Request> 类,在 app 模块之外(它在 masonite.request 模块内 )

如果您发现您遇到了这个异常,可以将对象移到自动加载的目录之外的单独目录中,然后可以使用不同的键绑定到容器中,或者简单的将类重命名一下。当使用模型的时候,那您可以将模型重命名为任何您喜欢的名称,然后指定 __table__ 属性到特定的表即可。

标注

尽管通过实际的容器键名称获取模型很有用,但是从容器中获取模型可能不是实际的,甚至不是最佳的方法。

推荐的方法是通过使用批注简单地获取类本身,以便您可以调整变量名称并确保整个应用程序的一致性。

from app.User import User

def show(self, author: User):
    author.find(1)

如果您觉得奇怪,务必去阅读 服务容器Resolve 部分文档。

自动加载类

您可能还想自己自动加载类。如果构建软件包并需要从某个位置获取所有类,甚至需要从某个目录获取所有实例,这可能会很有用。

类实例化

在 Masonite 计划任务模块中很有用,因为它可以获取 Task 类的所有子类。
自动加载类实例类似于:

from masonite.autoload import Autoload
from orator.orm import Model

classes = Autoload().instances(['app/models'], Model)
# returns {'Model': <config.database.Model>, 'User': <class app.models.User.User>, ...}

这将获取 app / models 目录中所有属于 Model 类实例的类。classes 属性包含找到的所有类的字典。

类收集

如果您不想获取作为另一个类的实例的类,那么我们可以简单地收集类:

from masonite.autoload import Autoload
from orator.orm import Model

classes = Autoload().collect(['app/models'])
# returns {'Model': <config.database.Model>, 'User': <class app.models.User.User>, ...}

仅获取应用程序类

您可能已经注意到,此自动加载类实际上将捕获所有找到的类。这些类也包括导入的类。

配置文件中默认自动加载功能仅加载特定于应用程序的类。

from masonite.autoload import Autoload
from orator.orm import Model

classes = Autoload().collect(['app/models'], only_app=True)
# returns {'User': <class app.models.User.User>, ...}

这将检查找到的类的名称空间,并确保其与正在搜索的路径分开。

实例化类

自动装带器找到的类本身就是未实例化的类。这对获取模型非常有用,但对获取其他对象(如命令)却不利。通过设计将命令放入容器时,需要实例化命令,以便 Masonite 和 cleo 可以找到它们。

我们可以通过传递另一个参数告诉自动加载器来实例化该类。这将简单地实例化对象,而无需传入任何参数。

如果您的类需要参数,则应该收集这些类并分别实例化每个类。

from masonite.autoload import Autoload
from orator.orm import Model

classes = Autoload().collect(['app/models'], only_app=True, instantiate=True)
# returns {'User': <app.models.User.User at 0x10e36d780>, ...}

您可以看到现在已实例化了所有找到的对象。

本文章首发在 LearnKu.com 网站上。

本译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。

原文地址:https://learnku.com/docs/masonite/2.3/ad...

译文地址:https://learnku.com/docs/masonite/2.3/ad...

上一篇 下一篇
贡献者:4
讨论数量: 0
发起讨论 只看当前版本


暂无话题~