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


38

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

私はそれを使用するために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番目の選択肢があることを認識させました。私はseparteプロジェクトにヘルパーコードを持っているので、このプロジェクトを個々のアプリケーションのソリューションに追加できます-これは、単一のプロジェクトを追加する以外は、単一ファイルの「リンクとして追加」のように機能します... Doc Brownが気づいたように、これは基本的に.dllをプロジェクトに追加する必要があることを意味します...

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


3
.NETの要件が高い場合に役立ちますので、そうです。しかし、私はそれが好きではありません... 40kbアプリのインストーラーはちょっとやり過ぎです:)
バルトス

3
さて、いつでもCosturaのようなものを使用できます。これはDLLをマージするためのツールです。すべての依存関係をEXEにマージして、単一のファイルを保持し、必要なライブラリを使用できます。これは、簡単にするために、ビルドプロセスに対して自動化できます。
クロルタン

2
ソリューションにプロジェクトを追加する場合、上記のすべての欠点を含めて、このプロジェクトのDLLを展開する必要があります。
Doc Brown

2
@DocBrown-神聖なくだらない、あなたは正しい:)
Bartosz

1
.csファイルまたはプロジェクトのリンクには別の欠点があります。これらの共有ファイルを多くのプロジェクトで使用しており、1つのプロジェクトで共有ライブラリに重大な変更が必要な場合、他のプロジェクトをリファクタリングする必要があります。コードが更新されたロジックを必要とする理由がない場合は、dllを参照することでそれを防ぎます。私は、共有プロジェクトにカスタム認証などが関係するときにこの問題に遭遇した開発チームの一員でした。顧客は新しいアプリケーションの変更を試みたいと思っているので、今度は何らかの方法で共通ライブラリをバージョン管理する必要があります。dllを使用してそれを行います。
エルセディル

回答:


13

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

個別のDLLを使用する

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

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

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

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


オーケー、どうもありがとう-だから、ヘルパークラスが他の外部dll(標準の.NETコードのみを含む)を参照しない限り、単純にリンクするのは憎まないことを正しく理解できますか?
バルトス

@Bartosz:外部DLLはありません。各ヘルパークラスは、理想的には他のヘルパークラスを使用しないか、同じファイルに格納されている他のヘルパークラスのみを使用する必要があります。正直に言うと、ヘルパークラスAが別のファイルに格納されたヘルパークラスBを必要とする状況をある程度管理できますが、このアプローチはうまく拡張できません。
Doc Brown

1
@PeterK。-うん、私はやった:)
Bartosz

1
@whatsisname:これが機能しなかったわけではありません。しかし、私にとってそれは、物事を単純化する解決策のようには聞こえません。もっと予期せぬ問題を引き起こす可能性のあるもののようです;-)
Doc Brown

1
@Ozkan:私たちの環境では、いくつかのネットワーク共有へのxcopy展開です(以前のバージョンをバックアップし、誰もが現在プログラムを使用していないことを確認するためのいくつかの追加手順があります-これは、最初に展開フォルダーの名前を変更する試みによって達成されます)。必要なDLLのリストをスクリプトにハードコーディングしているため、どのDLLをデプロイするかを知っています-その背後に魔法はありません。このソリューションは完璧ではありませんが、多くのユーザーが頻繁に使用するプログラムを除いて、ほとんどの場合に機能します。
Doc Brown

11

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


2

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

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

あなたはDLLを使用することを決定した場合は別の方法として、次のようなツールを使用することができますCostura埋め込まれたリソースとして実行可能ファイルで参照することを埋め込むことができます。それを使用するには、Costura.Fodyパッケージを追加するだけです:

Install-Package Costura.Fody

実際には、もう一つがあります-リンクとして追加埋め込まれたプロジェクトまたはファイルを、あなたも積極的に...ヘルパーファイルを介してすべての道のコードをデバッグすることができます
バルトシュ

1
@Bartosz正しいpdbファイルがあれば、「ヘルパーファイル」なしで「ずっと」デバッグできます。
ザック

Costuraを試してみましたが、本当に気に入っています!
バルトス

2

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を使用するように調整することが難しくなります。


1

3番目のオプションが最も適切です(別の「クラスライブラリ」プロジェクトとしてソリューションに追加します)。これにより、すべてのアプローチの利点が組み合わされます。

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

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

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


2
うーん、ソリューションとしてプロジェクトとして追加し、このプロジェクトを他のプロジェクトで参照すると、埋め込まれているのではなく、別の.dllとして作成されているように見えます...指定する必要があるものはありますか?
バルトス

1

開発者として、コードをデバッグできるようにユーティリティのソリューションの参照をアプリケーションに含めるのが好きです(また、ユーティリティの潜在的なバグも見つけてください!)。また、ユーティリティに加えられた変更は自動的にアプリケーションに含まれます。

そのため、実際の決定はユーティリティの成熟度に依存します!ユーティリティのバグについて不明な場合は、そのユーティリティの.csファイルを常に含めてバグを見つけてください。しかし、ユーティリティが十分に成熟していて、バグや結果が返されないことが確実な場合は、ユーティリティの機能強化の範囲はありません。先に進んでDLLファイルを含めることができます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.