假设我有一个客户,他有一份订单清单和一份愿望清单。在我的模型中,我有一个ClientRepo
,OrderRepo
和WishListRepo
。在控制器中,我应该在哪里实例化这些存储库?将它们作为类级实例是一个好主意吗?
component ClientController
{
ClientRepo = new ClientRepo();
OrderRepo = new OrderRepo();
WishListRepo = new WishListRepo();
public void function HomePage(any event)
{
var clientId = event.getValue("id");
var client = ClientRepo.getClientById(clientId);
var orders = OrderRepo.getOrdersForClientId(clientId);
// put the variables into the event object for the view to access
}
}
或者更好的设计是在函数中实例化它们吗?
public void function HomePage(any event)
{
var ClientRepo = new ClientRepo();
var orderRepo = new OrderRepo();
var wishListRepo = new WishListRepo();
// rest of the code is the same
}
这里的假设是ClientController
中的其他函数需要访问相同的存储库。
此外,控制器的使用寿命是多少?它是每次请求一次,每次会话一次,还是每次应用一次?
答案 0 :(得分:3)
披露:我是Model-Glue项目的贡献者,所以我可能知道我在说什么: - )
CFML没有真正的类级实例,如Java。如果你想要单例(在应用程序的许多部分共享一个实例),你需要将它放在共享范围(yuk!)或使用bean容器。幸运的是,Model-Glue与ColdSpring(CFML的流行bean容器)紧密集成,而Model-Glue 3使您可以比以往更轻松地在控制器中使用ColdSpring bean。
首先,编辑ColdSpring.xml以包含单身人士的定义:
<bean id="ClientRepo" class="MyApp.model.client.ClientRepo"/>
<bean id="OrderRepo" class="MyApp.model.order.OrderRepo"/>
这当然只是一个简单的例子。 ColdSpring是一个基于Java Spring的强大的依赖注入框架。查看ColdSpring Quickstart以了解您可以使用它做的其他一些事情。
一旦在ColdSpring中定义了bean,你可以让你的控制器通过getModelGlue()。getBean()调用显式地询问它们。然而,更好的方法是声明控制器对这些bean的依赖性,并让Model-Glue将它们注入您的控制器中。可以在ModelGlue.xml或控制器CFC中声明依赖项。以下是如何在控制器中声明bean依赖项:
component ClientController beans="ClientRepo,OrderRepo"
{
public void function HomePage(any event)
{
var clientId = event.getValue("id");
var client = beans.ClientRepo.getClientById(clientId);
var orders = beans.OrderRepo.getOrdersForClientId(clientId);
// put the variables into the event object for the view to access
}
}
任何声明的bean都由框架注入控制器的“beans”范围,因此它们可以被任何侦听器函数使用。但请注意,在初始化之后发生bean注入,因此您不能将它们用作init()函数。
ColdSpring bean默认是单例,所以如果将相同的ColdSpring bean注入到多个控制器中,它们都会以相同的bean实例结束。如果在bean定义中添加singleton =“false”,那么每个控制器最终会得到一个不同的实例;我想不出你为什么要那样做。
有关Model-Glue中bean注入的更多信息,请查看Bean Injection HOWTO上的Model-Glue Wiki。
Model-Glue 3.1在框架初始化时将所有控制器实例化为单例,因此每个控制器每个应用程序创建一次。未来版本可能会延迟控制器的实例化,直到它们首次需要为止,因此最好不要对它们何时初始化进行假设。如果你真的需要在应用程序初始化时执行的控制器中有一些代码,我建议你添加一个onApplicationStart监听器。