使用文件替换来替换服务实现
Angular 允许通过 fileReplacements
文件替换 > 在 angular.json 中。一个常见的用例是替换文件environment.ts以针对特定构建,例如使用ng build --configuration staging
以及configurations
中的以下条目angular.json:
"staging": {
...,
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.staging.ts"
}
]
}
上面的效果很好,并且它的用例非常清晰。
但是,让我们假设这种情况,我想通过文件替换来替换服务(和其他文件)。一项特定服务的示例:
// service.interface.ts
export interface IService { doSomething(): void; }
// service.mock.ts
@Injectable()
export interface Service implements IService {
doSomething(): void { throw Error(); }
}
// service.bar.ts
@Injectable()
export interface Service implements IService {
doSomething(): void { // bar specific implementation }
}
// service.foo.ts
@Injectable()
export interface Service implements IService {
doSomething(): void { // foo specific implementation }
}
// app.component.ts
import { Service } from './service.mock';
...
export class AppComponent {
constructor(private service: Service) {
this.service.doSomething();
}
}
angular.json 中的 configurations
如下所示:
"foo": {
...
"fileReplacements": [
{
"replace": "src/app/service.mock.ts",
"with": "src/app/service.foo.ts"
}
]
},
"bar": {
...
"fileReplacements": [
{
"replace": "src/app/service.mock.ts",
"with": "src/app/service.bar.ts"
}
]
}
通过使用 ng build --configuration foo
或 ng build --configuration bar< /code> 我现在可以确定通过
AppComponent
中的 this.service.doSomething();
调用哪个实现 - foo 或 < em>bar 具体一个。长话短说:这个解决方案感觉有点奇怪。请记住,我可能有几个服务采用这种方式,还有路由和其他文件(导致相当长的 fileReplacements
)。
我想知道:1.)文件替换是否适用于此用例? 2.) 是否有任何严重的缺点或缺点? 3.)有哪些可能的替代方案,或者更确切地说,什么是更像 Angular 的方式(也许类似于依赖注入)?
如果需要更多详细信息,请告诉我。
Angular allows file replacements via fileReplacements
in the angular.json. One common use case is to replace the file environment.ts in order to target a certain build, e.g. with ng build --configuration staging
and the following entry in configurations
within the angular.json:
"staging": {
...,
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.staging.ts"
}
]
}
The above works well and its use case is pretty clear.
However, let's assume the situation, that I want to replace services (and other files) via file replacements. An example for one specific service:
// service.interface.ts
export interface IService { doSomething(): void; }
// service.mock.ts
@Injectable()
export interface Service implements IService {
doSomething(): void { throw Error(); }
}
// service.bar.ts
@Injectable()
export interface Service implements IService {
doSomething(): void { // bar specific implementation }
}
// service.foo.ts
@Injectable()
export interface Service implements IService {
doSomething(): void { // foo specific implementation }
}
// app.component.ts
import { Service } from './service.mock';
...
export class AppComponent {
constructor(private service: Service) {
this.service.doSomething();
}
}
And configurations
in the angular.json looks like:
"foo": {
...
"fileReplacements": [
{
"replace": "src/app/service.mock.ts",
"with": "src/app/service.foo.ts"
}
]
},
"bar": {
...
"fileReplacements": [
{
"replace": "src/app/service.mock.ts",
"with": "src/app/service.bar.ts"
}
]
}
By using ng build --configuration foo
or ng build --configuration bar
I can now determine which implementation gets called via this.service.doSomething();
in AppComponent
- either the foo or the bar specific one. Long story short: this solution feels a bit odd. And keep in mind, that I might have a couple of services going this way, also routing and other files as well (resulting in a pretty long fileReplacements
).
I was wondering: 1.) Are file replacements intended for this use case?; 2.) Are there any critical disadvantages or downsides?; and 3.) What are possible alternatives or rather what is the more Angular-like way (maybe something like dependency injection)?
Let me know, if further details are needed.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
文件替换的优点是您不会将所有未使用的服务与代码捆绑在一起。如果所有未使用的服务都被捆绑在一起并不困扰您,那么 DI 可能是您的一个很好的解决方案(继续阅读)。
您可以将变量添加到环境文件中,然后在
NgModule
中创建一个提供程序。 这是一个工作示例您将创建
x
个所有服务都将扩展基本服务。然后,该基本服务将具有一些与之关联的抽象数据,甚至可能是您的孩子可以使用的一些方法/属性。然后,您可以在模块中创建一个提供程序,甚至可以在其他一些提供
服务
的组件中创建一个提供程序。然后,当您将其注入组件/服务/指令等时,工厂将被执行,并根据您设置的环境变量决定向调用者提供哪个服务。我们不是在
FooService
或BarService
上进行 DI 注入,而是在基础服务上进行。创建后将运行工厂并返回正确的类。The advantage of file replacement is that you won't have all the unused services bundled with the code. If it doesn't bother you that all of the unused services do get bundled then DI might be a good solution for you (Read on).
You could add a variable to your environment file(s) and then create a provider in your
NgModule
. Here is a working exampleYou would create
x
number of services that all would extend a base service. This base service would then have some abstract data associated with it and may even some methods/properties that your children could use.You would then create a provider in your module or even some other component that would provide
Service
. When you then inject it into your components/services/directives etc. the factory will get executed and decide which service to provide to the caller based on your environment variable that is setup.Instead of doing DI injection on
FooService
orBarService
we do it on the base service. Which when created will run the factory and return the proper class.