ASP.NET Coreのコラムは、ウクライナのDmitry Ukraniansの責任者であるDmitry Sikorskyによる出版物で続きます。 次の記事では、DmitryがASP.NET Coreのプレゼンテーションでの非標準作業の経験について語っています。 このコラムの以前の記事は、 #aspnetcolumn -Vladimir Yunevでいつでも読むことができます。最近、私はASP.NET 5(現在のASP.NET Core 1.0)のモジュラーフレームワークに懸命に取り組んでいます。 このプロジェクトのフレームワーク内では、さまざまなタスクを解決する必要があり、そのうちの1つは、非標準の場所だけでなく、Webアプリケーションのメインアセンブリの外部にあるプレゼンテーションで作業していました。 この記事では、そのようなものが必要な場合にどのような選択肢があるかを説明します。
Webアプリケーションのメインアセンブリ内の非標準の場所のビュー
突然、何らかの理由でビューが彼が設定したViewsフォルダーの外にある場合(ただし、同時にアプリケーションのメインプロジェクト内に残っている場合)、これについてRazor'yに通知する必要があります。 このために以前にRazorViewEngineから派生したクラスを作成する必要がある場合、少し簡単になりました。
アドバイス! 自分ですべて試すか、GitHub https://github.com/DmitrySikorsky/AspNet5Viewsからソースコードをダウンロードしてください 。まず、IViewLocationExpanderインターフェイスを実装します(文字列定数の「{1}」がコントローラーの名前に、「{0}」がアクションの名前に置き換えられることを思い出します)。
public class CustomViewLocationExpander : IViewLocationExpander { public IEnumerable<string> ExpandViewLocations(ViewLocationExpanderContext context, IEnumerable<string> viewLocations) { List<string> expandedViewLocations = new List<string>(); expandedViewLocations.AddRange(viewLocations); expandedViewLocations.Add("/Views/SomeExtraFolder/{1}/{0}.cshtml"); return expandedViewLocations; } public void PopulateValues(ViewLocationExpanderContext context) { } }
次に、結果のクラスのインスタンスをConfigureServicesメソッドに「登録」します。
services.Configure<RazorViewEngineOptions>(options => { options.ViewLocationExpanders.Add(new CustomViewLocationExpander()); } );
以上で、Razorは新しいパフォーマンスのレイアウトに注目します。
他のアセンブリのリソースビュー
実際、私は利点については知りません(しかし、欠点については知っています!)このアプローチの次のアプローチについては、まだそれについて話す必要があると思います。
ビューをリソースとしてアセンブリに配置するには、対応するプロジェクトのproject.jsonに次の行を追加する必要があります(実際、ビューだけがリソースに変換されるわけではありません)。
「リソース」:「表示/ **」
そのような表現が後でRazorによって検出されるようにするには、IFileProviderインターフェイスを実装し、結果のクラスのインスタンスをメインプロジェクトのConfigureServicesメソッドの対応するプロパティに割り当てる必要があります。
services.Configure<RazorViewEngineOptions>(options => { options.FileProvider = this.GetFileProvider(this.applicationBasePath); } );
GetFileProviderメソッドは、CompositeFileProviderクラスのインスタンスを作成します。実際には、複数の異なるプロバイダーを結合します(この場合、これらはメインプロジェクトと指定されたアセンブリのリソースを持つフォルダー内の物理ファイルです)。
このアプローチの主な欠点は、メインプロジェクトで明示的に参照されていないアセンブリで定義された型を使用して表現を入力できないことです。 たとえば、ビュー自体が配置されているプロジェクトで定義されているタイプは使用できません。 これは、リソース形式の表現が実行時にすでにコンパイルされているため、モデルのタイプが見つからないためです。 依存関係を明示的に追加できる場合、これは問題になりませんが、実行時にアセンブリを動的にロードする場合、これを行うことはできません。 次のアプローチはこの問題を解決します。
(実際、私が理解しているように、これはまだ解決できます。この問題については、 https : //github.com/aspnet/Mvc/issues/3413で説明しましたが、まだこの議論を超えていません。)
他のアセンブリのプリコンパイル済みビュー
おそらく、アプリケーションのさまざまなアセンブリにリプレゼンテーションを配置する必要がある場合(たとえば、独立したパーツに分割してメンテナンスとチームワークを簡素化するため)、これが最適なオプションです。
前のケースのように、プリコンパイル済みビューを使用する場合、公開時にビューをサーバーにコピーする必要はありません。これにより、このプロセスが大幅に高速化されます(多くのcshtmlファイルの代わりに、1つのdllファイルのみがコピーされます)。 しかし、リソース形式の表現とは異なり、そのような表現は、名前が示すように、実行時ではなくプロジェクトアセンブリの段階でコンパイルされます。これにより、まず、すべてのエラーを事前に識別できます。特定のページにアクセスするときにアプリケーションを起動するときに時間を節約します。
コンパイラに強制的にビューをコンパイルするには、対応するプロジェクトでRazorPreCompilationクラスを作成し、RazorPreCompileModuleから継承し、EnablePreCompilationメソッドをオーバーライドしてtrueを返し、最後に\ Compiler \ PreProcessフォルダに入れるだけで十分です。
public class RazorPreCompilation : RazorPreCompileModule { protected override bool EnablePreCompilation(BeforeCompileContext context) => true; }
メインアプリケーションプロジェクトで、他のアセンブリからプリコンパイルされたビューを使用する必要があることをRazorに伝えるには、これらのアセンブリのセットを適切なメソッドに渡すだけです。
services.AddMvc() .AddPrecompiledRazorViews( new Assembly[] { Assembly.Load(new AssemblyName("AspNet5Views.PrecompiledViews")) } );
これで機能します。
上記で書いたように、ビューはプロジェクト全体のアセンブリ段階でコンパイルされるため、メインアプリケーションプロジェクトで参照されていない型でビューを分類できます。
結論
一般に、すべては非常に簡単です。 最後の2つのアプローチには重大な欠点があります。たとえば、レイアウト全体の細部まで変更するために、アプリケーション全体を再起動する必要があります。 ただし、アプリケーションを本当に複数の部分に分割する必要がある場合は、アプリケーションのすべての部分からメインプロジェクトにビューをコピーするよりもはるかに便利です。
この記事に記載されているすべてを試すことができるように、小さなテストプロジェクトを用意しました: https : //github.com/DmitrySikorsky/AspNet5Views 。
著者向け
ご友人、ご自身の資料でコラムをサポートすることに興味がある場合は、すべての詳細を議論するためにvyunev@microsoft.comまでご連絡ください。 ASP.NETおよびその他のトピックについて興味深い話ができる著者を探しています。
著者について
シコルスキー・ドミトリー・アレクサンドロヴィチ
Ubrainians Company(http://ubrainians.com/)
オーナー、マネージャー
ドミトリーシコルスキー