我有一个rest-client对象,它在生产环境中将指向一个安静的服务器并与之通信。但在开发模式下,它只是简单地使用浏览器的存储空间来使用。
我认为正确的方法是实现两个接口实现,一个用于生产,一个用于开发。这样,应用程序的其余部分不需要了解生产/开发,并且可以进行相同的测试。我需要做的就是找到一种方法为每个环境注入正确的实例。顺便说一句,我不想在生产代码中包含开发版本!
有谁知道怎么做?
[UPDATE]
我使用Angular cli开始我的项目,所以我使用Webpack(我想!)。我不想使用外部模拟服务器,因为我更喜欢将测试/开发环境与外部依赖关系隔离开来。这就是我需要在我的前端项目上工作的本身。此外,即使我的问题集中在休息客户端,但当然这个问题可以推广到任何其他单例注射。
我问这个问题,因为我使用的其他DI框架(即Spring)这样做是框架的一部分。所以我期待在这里看到同样的东西。
此时,我知道我可以利用if (environment.production) {
import { RestClientService } from './rest-client.service';
}
else {
import { MockRestClientService as RestClientService } from './mock-rest-client.service';
}
ERROR in ... Duplicate identifier 'RestClientService'.
ERROR in ... An import declaration can only be used in a namespace or module.
来检查它是否处于生产模式。但首先,这是一个运行时变量,但我想我正在寻找一个编译时的变量(我不确定)。此外,即使我们有该变量,但以下代码导致编译错误:
foreach (DataRow row in dtBills.Rows)
{
classes.UtilityBill ub = new classes.UtilityBill(row);
if (ub.ApprovedBy > 0)
{
if (ub.RemainingBalance() > 0) { totalOutstanding += ub.RemainingBalance(); numberOfUnpaidBills++; }
if (ub.RemainingBalance() > 0 && ub.IsOverDue()) { numberOfOverdueBills++; }
}
else
{
if (ub.ApprovedBy == 0)
{
awaitingApproval++;
}
else
{
rejectedBills++;
}
}
}
答案 0 :(得分:2)
export function restClientFactory(http: HttpClient): RestClientService {
if (environment.production) {
return new RestClientService(http);
} else {
return new MockRestClientService();
}
}
@NgModule({
providers: [
{ provide: RestClientService, useFactory: restClientFactory, deps: [ HttpClient ] },
],
})
class AppModule {}
使用条件import
语句的方法不起作用,因为只允许在文件的顶层使用静态import
语句。它们不能嵌套在if/else
语句中。您可以使用动态import()
来克服此问题,但这也会导致两个实现都包含在您的包中。
不幸的是,没有技术可能在Spring中进行DI的编译时配置。
运行时检查的主要问题是两个实现都将包含在您的生产包中。您可以依赖tree-shaking(生成版本的一部分)来确保您的模拟客户端不包含在生产包中。
由于environment.production
变量永远不会改变,因此您可以预期if/else
的一个分支永远不可访问,因此可以通过树摇动过程从捆绑中删除。问题是,做树震动的工具无法理解它,因为变量不是声明为const
,而是作为对象的属性。
如果您将export const production = true
添加到environment.prod.ts
并将export const production = false
添加到environment.ts
并在if/else
语句中使用此变量,则其中一个分支应成功树摇动来自生产包。
请注意,此方法依赖于Angular CLI的实现细节。不过我已经成功地在我的一个项目中使用它超过一年了。