web-dev-qa-db-ja.com

.csファイルをプロジェクトにリンクするよりも.dllファイルを使用する利点(私の独自の汎用ヘルパークラス/拡張メソッドの場合)

作成したすべてのアプリケーションで使用するヘルパープロジェクトがあります。これには、いくつかの拡張メソッドと一連の汎用ヘルパークラス、コントロールなどが含まれています。ヘルパープロジェクトは随時更新/拡張しています。これらは通常、小規模で無関係なプロジェクトであり、それらすべてに取り組んでいるのは私だけです。

私はそれを使用するために2つのアプローチを試しました

  • 使用する各プロジェクトに.csファイルを直接追加(リンクとして追加)
  • .dllとしてコンパイルし、参照として追加します

これらのアプローチにはいくつかの利点と欠点があります。
最初の1つ:

  • ヘルパークラスがexeファイルにコンパイルされるため、単純です。したがって、正常に機能する単一の.exeファイルを非常に簡単に提供できます。リンクとして追加するので、ヘルパーを使用するプロジェクトをビルドするときはいつでも、ヘルパーファイルが最新バージョンになることを確信できます。
  • ファイルを分離できるため、.NET 4.0で正常に動作する拡張メソッドを.NET 4.5を必要とする拡張メソッドとは別に参照できるため、アプリ全体が.NET 4.0で実行できるため、さらにシンプルです。
  • コードを介してデバッグすることができ、ブレークポイントなどのすべての利点があります...
  • 「ベストプラクティス」ではないようです

2つ目:

  • 正しいアプローチのようですが、次のようになります。
  • 別の.dllファイルを提供する必要があります。これは、何らかの理由でユーザーにとってはるかに困難です(.dllなしでプログラムを共有する傾向があり、起動時にクラッシュします)。
  • 単一の.dllにコンパイルされるため、.NETの最新バージョンが必要になります。多くのユーザーには.NET 4.5がなく、これを必要とするのは私のヘルパークラスの一部の要素のみです。つまり、一部のユーザーを強制できます。理由もなくシステムを更新する
  • また、プログラムを更新するたびに、.dllファイルも配信するようにする必要があります。ただし、前回のバージョンから変更されているかどうかはわかりません(変更されている可能性がありますが、同じバージョンでもかまいません)。追加の作業であるアセンブリバージョンを追跡せずに、それを判断する簡単な方法はわかりません。今のところ、プログラムを更新するときは、更新されたexeのみを配信し、小さくて目立たないようにします。

では、ここで.dllファイルを使用する実際の利点は何ですか?すべてのアプリケーションとヘルパーファイルのコードを編集するのは私だけです。


また、明確にするために-通常、アプリはごくわずかですが、ヘルパークラスに含まれるコードはそれらすべてに対して完全に一般的です(単純な文字列比較、パス、XML操作など)。


実際、3人目の選択肢があることを誰かが私に気づかせました。別のプロジェクトにヘルパーコードがあるので、このプロジェクトを個別の各アプリケーションのソリューションに追加できます。これは、単一のプロジェクトのみを追加することを除いて、単一のファイルの「リンクとして追加」のような働きをします...しかしDoc Brownが気づいたように、これは本質的に.dllをプロジェクトに追加する必要があることを意味します...

DLLファイルを使用しないことを支持するもう1つのことは、ヘルパークラスをアクティブにデバッグする機能です...

38
Bartosz

あなたはすでに長所と短所のほとんどを発見しました。参照としてcsファイルを使用すると、実際に軽量化され、多くの場合管理が容易になります。ただし、csファイルが完全に自己完結型で、特別なビルド要件がない場合にのみ、このアプローチを使用することをお勧めします。

別のDLLの使用

  • 他のユーティリティまたはライブラリへの依存関係を明示的にします(そのような依存関係がない限り、正常に動作します)

  • 特定のビルド構成を定義することができます(たとえば、クラスがx86構成でのみ機能する場合、または少なくとも.NET 4.0が必要な場合、アセンブリのビルド構成はこの要件を明示的にします)。

したがって、特に、単一クラスの自己完結型コンポーネントが多数ある場合は、ファイルへの参照を使用することで問題ありませんが、他のコンポーネントを参照するコンポーネントがある場合、または特定のビルド要件がある場合は、DLLを使用することをお勧めします。

多くの個別DLLの管理に関する問題を軽減するには、インストーラーパッケージを作成するか、または一連のアセンブリを単一の実行可能ファイルに埋め込むことができる ILMerge を利用します。私たちの環境では、アプリケーションごとにデプロイスクリプトを使用することで、問題に異なる方法で対処しています。このスクリプトにより、新しいアプリケーションリリースが公開されたときに、必要なすべてのDLLが常に本番環境に配信されます。

13
Doc Brown

DLLは、アプリケーションが大きく、アプリケーション全体ではなく、更新が必要な部分がある場合に便利です。したがって、MS Wordを作成している場合、DLLにスペルチェックコードを含めると、MS Word全体を更新しなくても更新できるので便利です。書き込みは小さなユーティリティアプリ(または、たまたま同じコードを使用する一連の自己完結型アプリ)であり、コードがアプリに埋め込まれているかどうかに関係なく、大きな違いはありません。

11
dcguest

あなたはあなたの質問でそれをほとんど要約しました、私は追加するためにいくつかのポイントを持っています。

Mono Options は、最初のアプローチを非常にうまく使用したNuGetパッケージの良い例です。

あるいは、dllを使用する場合は、 Costura などのツールを使用して、その参照を実行可能ファイルに埋め込みリソースとして埋め込むことができます。使用するには、Costura.Fody パッケージ:

Install-Package Costura.Fody
2
Justin

DLLがより有益かどうかは、いくつかの要因に依存します。

  1. コードのサイズ(コンパイル時)。
  2. いくつのexeがそれを使っているか。
  3. コードを更新する頻度。
  4. Exeが一緒に保持されることを意図しているか、完全に別々に存在するかどうか。

共有ライブラリの目的は、複数の実行可能ファイルに共通のコードを取得して一元化し、すべての実行可能ファイルがコピーを共有できるようにすることです。これは、スペースを節約し、コードの更新を容易にすることを目的としています。

ヘルパークラスのコードの量が非常に少ない場合は、コードをdllに移動する価値がない場合があります。dll内にあるコードのオーバーヘッドによって、集中化することによるスペース節約のメリットが妨げられる可能性があるためです。

さらに、少数の実行可能ファイルのみを作成する場合は、各実行可能ファイルのコードのサイズが問題にならないほど小さい可能性があります。ただし、同じコードを使用する実行可能ファイルが多いほど、コードをdllに移動するほうが有益です。

簡単な例として、ヘルパークラスがexeファイルで128バイトにコンパイルされるが、dllに移動した場合、dllは512バイトであるとします。実行可能ファイルが3つしかない場合は、実行可能ファイルにコードを含めることでスペースを節約できます。ただし、5つの実行可能ファイルがある場合は、コードの5つのコピー(5 * 128 = 640バイト)によって占められる合計容量が、必要な容量よりも大きいため、dllを使用するほうがよいでしょう。 dll(512バイト)にコードを含める。

たとえば、ヘルパーコードにバグを見つけたとします。組み込まれたコードですべての実行可能ファイルをコンパイルした場合は、すべての実行可能ファイルを再コンパイルしてから、再コンパイルしたバージョンを再配布する必要があります。コードをdllにコンパイルした場合、1つのdllを再コンパイルして再配布するだけで、それを使用するすべての実行可能ファイルに対してバグが自動的に修正されます。

最後に、プログラムがDLLを見つけるには、DLLを探す場所を知っている必要があります。すべての実行可能ファイルを一緒に保持している場合は、dllを同じディレクトリに置くだけですぐに見つかります。それらを意図的に分離しておくと、同じdllを使用するようにそれらを調整することが難しくなります。

2
Pharap

3番目のオプションが最も適切です(ソリューションに別の「クラスライブラリ」プロジェクトとして追加します)。これは、すべてのアプローチの利点を兼ね備えています。

  • 「ヘルパープロジェクト」は、すべての異なるプロジェクトで常に最新です。
  • 変更をすばやく確認したい場合は、プロジェクトのコードを参照できます。
  • 毎回正しい.NETバージョン用にビルドできます。
  • とにかくexeにDLLを埋め込むことができるので、ビルドの一部としてそれだけを使用できることを心配しないでください。

私たちは常にこれを行っており、私は何もできませんが、このアプローチをお勧めします。

あなたが言及していない別の4番目の選択肢は、それをプライベートNuGetリポジトリに置くことです。これにより、正しくバージョン管理し、各ソリューションで追加のプロジェクトなしでそれを参照できます。

1

開発者として、コードをデバッグできるように(そしてユーティリティの潜在的なバグを発見できるように)、ユーティリティのソリューションのリファレンスを常にアプリケーションに含めます。また、ユーティリティに加えられた変更はすべてアプリケーションに自動的に含まれます。

したがって、実際の決定は、ユーティリティの成熟度によって異なります!ユーティリティのバグについて不明な点がある場合は、常にそのユーティリティの.csファイルを含めてバグを見つける必要があります。しかし、ユーティリティが十分に成熟していて、バグが発生しても結果が返されないことが確かな場合ユーティリティの拡張の範囲ではないので、先に進んでDLLファイルを含めることができます。

1
saruchi arora