2017-10-19 18 views
2

私は、実稼働環境で安静なサーバーを指し示し、それと通信するrest-clientオブジェクトを持っています。しかし、開発モードでは、使いやすさのために単にブラウザのストレージを使用します。開発と生産のための別の@注射可能物

私はこれを行う正しい方法は、インターフェイス用の2つの実装、つまり本番用と開発用の2つのインターフェイスを実装することだと思います。このようにして、アプリケーションの残りの部分は生産/開発について知る必要はなく、まったく同じようにテストすることができます。私がする必要があるのは、各環境に適切なインスタンスを注入する方法を見つけることだけです。そして、私は、開発コードをプロダクションコードにまったく含まないことを好みます!

誰でもこれを行う方法を知っていますか?

[UPDATE]

私はWebPACKのは、使用していますので、私のプロジェクトをキックオフする角度CLIを使用してきた(と思います!)。テスト/開発環境を外部の依存関係から隔離したままにしておくことを好むため、外部モックサーバーを使用しないことをお勧めします。そうすれば、私のフロントエンドプロジェクトで必要なのはそれだけです。また、私の質問は、残りのクライアントに焦点を当てていますが、もちろん、この質問は、任意の他のシングルトン注射可能に一般化することができます。

私が(つまりSpringを使って)作業していた他のDIフレームワークでは、フレームワークの一部なので、この質問をしています。だから私はここでも同じことを期待していた。

この時点で、environment.productionを活用して、運用モードになっているかどうかを確認できます。しかし、まず第一に、これは実行時変数ですが、私はコンパイル時のものを探していると思います(私は確信していません)。動作しない条件import文と

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 {} 

アプローチ:このため

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. 
+0

どのビルドツールを使用しますか? (つまり、webpack、rollupまたは何か?)私が知る限り、TypeScript自体はこのような場合には役立ちません。ビルド処理中にインクルードパスをこのファイルに「置き換える」必要があります。 –

+0

もちろん、あなたはいつでも実行時にいくつかの設定やそのようなものに基づいて作成することができますが、それらの実装のうちの2つはコードで行い、アプリケーション自体は正しいものを使用します。 –

+0

なぜMockBackendを使用せず、Httpコール(https://semaphoreci.com/community/tutorials/testing-services-in-angular-2)をインターセプトして、あなたのユースケースを知りたいのですか?) – cyberpirate92

答えて

2

使用factory provider:また、我々は変数ことを持っているが、にもかかわらず、次のコードはコンパイルエラーにつながります静的なimportステートメントはファイルの最上位レベルでのみ許可されているためです。彼らはif/elseステートメント内に入れ子にすることはできません。これを克服するために動的なimport()を使用することができますが、これは両方の実装があなたのバンドルに含まれるようにもつながります。


残念ながら、SpringのようにDIのコンパイル時の設定を行う技術的な可能性はありません。

ランタイムチェックの主な問題は、両方の実装が本番バンドルに含まれることです。プロダクションビルドの一部であるtree-shakingを利用することで、モッククライアントが本番バンドルに含まれないようにすることができます。

environment.production変数が決して変更されないので、if/elseの1つのブランチは決して到達できないため、ツリーシェイク処理によってバンドルから削除できます。変数はconstとして宣言されているのではなく、オブジェクトのプロパティとして扱われるため、ツリーシェイクを実行するツールではそれを理解できないという問題があります。

あなたはenvironment.tsenvironment.prod.tsexport const production = falseexport const production = trueを追加し、分岐の1つは、生産バンドルから振とう首尾木でなければなりませんif/else文でこの変数を使用する場合。

このアプローチは、Angular CLIの実装の詳細に依存しています。それにもかかわらず、私は1年以上私のプロジェクトの1つで成功裏に使用しました。

関連する問題