タグ付けされた質問 「dependency-injection」

Dependency Injectionは、コンポーネントの依存関係(オブジェクトのインスタンス、プロパティ)がコンストラクタ、メソッド、またはフィールド(プロパティ)を介して設定される設計パターンです。これは、より一般的な依存関係の反転の特殊な形式です。

2
依存性注入と静的メソッド
文字列を受け取り、文字列を出力するメソッドを使用してクラスにアプローチする方法について、今日、別の開発者と興味深い議論をしました。 例の目的のために完全に構​​成されている次のようなものを想像してください public string GetStringPart(string input) { //Some input validation which is removed for clarity if(input.Length > 5) return input.Substring(0,1); if(input.Substring(0,1) == "B") return input.Substring(0,3); return string.empty; } 文字列入力に基づいたロジックを持つ関数は、DIを使用してプロジェクトに追加され、DIコンテナが配置されています。この新しいクラスをインターフェイスで追加し、必要な場所に挿入しますか、それとも静的クラスにしますか?それぞれの長所と短所は何ですか?どこで必要なときにアクセスするだけでなく、コンストラクター注入で使用するようにしたい(またはしたくない)のはなぜですか。

5
ほぼ全員が共通のデータ構造にアクセスする必要がある場合の依存性注入の利点は何ですか?
OOPでグローバルが悪である理由はたくさんあります。 共有を必要とするオブジェクトの数またはサイズが大きすぎて関数パラメーターで効率的に渡されない場合、通常はグローバルオブジェクトではなく依存性注入をお勧めします。 しかし、ほとんどすべての人が特定のデータ構造について知る必要がある場合、なぜ依存性注入がグローバルオブジェクトよりも優れているのでしょうか? 例(特定のアプリケーションを深く掘り下げることなく、ポイントを一般的に示すための簡略化されたもの) 種類、名前、色、速度、位置など、膨大な数のプロパティと状態を持つ仮想車両が多数あります。多数のユーザーがそれらをリモートコントロールでき、膨大な数のイベント(両方ともユーザー、開始および自動)は、多くの状態またはプロパティを変更できます。 素朴な解決策は、それらのグローバルコンテナを作成することです。 vector<Vehicle> vehicles; どこからでもアクセスできます。 よりOOPに適したソリューションは、コンテナーをメインイベントループを処理するクラスのメンバーにし、コンストラクターでインスタンス化することです。それを必要とし、メインスレッドのメンバーであるすべてのクラスには、コンストラクターのポインターを介してコンテナーへのアクセスが許可されます。たとえば、外部メッセージがネットワーク接続を介して着信した場合、解析を処理するクラス(接続ごとに1つ)が引き継ぎ、パーサーはポインターまたは参照を介してコンテナーにアクセスできます。解析されたメッセージの結果、コンテナの要素が変更された場合、またはアクションを実行するためにそこからデータが必要な場合、信号やスロットを介して数千の変数を投げる必要なく処理できます(または、それらをパーサーに保存して、パーサーを呼び出した人が後で取得できるようにします)。もちろん、依存性注入を介してコンテナへのアクセスを受け取るすべてのクラスは、同じスレッドの一部です。異なるスレッドは直接アクセスしませんが、ジョブを実行してからメインスレッドに信号を送信すると、メインスレッドのスロットがコンテナを更新します。 ただし、クラスの大部分がコンテナにアクセスできるようになった場合、グローバルとはどう違うのでしょうか?非常に多くのクラスがコンテナ内のデータを必要とする場合、「依存性注入方法」は単なる偽装グローバルではありませんか? 答えの1つはスレッドセーフです。グローバルコンテナを乱用しないように注意を払っていますが、近い将来、他の開発者が近い締め切りの圧力の下で、すべてを気にせずに別のスレッドでグローバルコンテナを使用する可能性があります衝突の場合。ただし、依存性注入の場合でも、別のスレッドで実行されている誰かにポインターを与えると、同じ問題が発生する可能性があります。

2
「継ぎ目」という言葉の理解に関する問題
私はMark Seemannによる「.NETでの依存性注入」を読んでいます(それは素晴らしいですし、必需品です)。著者はよく「seam」という言葉を使用します。しかし、私はそれが何を意味するのか理解できません。この単語の使用例を次に示します。 第7章では、ASP.NET MVC、WPF、WCFなどのさまざまな具体的なフレームワークでオブジェクトを構成する方法について説明します。すべてのフレームワークがDIを同等にサポートしているわけではありません。また、DIをサポートしているフレームワークであっても、その方法は大きく異なります。各フレームワークについて、そのフレームワークでDIを有効にするSEAMを特定することは困難です。ただし、そのSEAMが見つかると、この特定のフレームワークを使用するすべてのアプリケーションのソリューションが得られます。第7章では、最も一般的な.NETアプリケーションフレームワークに対してこの作業を行いました。フレームワークSEAMSのカタログと考えてください。 この言葉を理解するのを手伝ってくれて感謝しています。

2
貧血ドメインモデルとドメインサービスインジェクション
貧血のドメインモデルは、 Martin Fowler氏によってドメイン駆動設計におけるアンチパターンとして記載されています。ドメインモデルでビジネスロジックを使用するには、多くの場合、ドメインサービスが使用されます。ただし、ドメインモデルへのドメインサービスの注入は、Vaughn Vernonにとって有害で​​あると考えられています(「ドメイン駆動設計の実装」を参照)。 私の意見では、これらの意見は矛盾している、これは本当ですか?両方のポイントをどのように考慮することができますか? それは実際にされたドメインサービスと豊富なドメインモデルは、注入された対貧血のドメインモデルと通常のドメインサービス?

7
抽象化はコードの可読性を低下させる必要がありますか?
一緒に仕事をしている優秀な開発者が、私たちが継承したコードに機能を実装するのに苦労したことを最近教えてくれました。彼は、問題はコードを追跡するのが難しいということだと言いました。そのことから、私は製品をより深く見て、コードパスを確認することがどれほど難しいかを理解しました。 非常に多くのインターフェースと抽象レイヤーを使用していたため、物事の始まりと終わりを理解しようとするのは非常に困難でした。私は過去のプロジェクト(きれいなコードの原則に気付く前に)を見ていた時間について考えさせられ、主にコードナビゲーションツールが常にインターフェイスに到達するため、プロジェクトを回避することは非常に困難であることがわかりました。具体的な実装や、プラグインタイプのアーキテクチャで何かが接続されている場所を見つけるには、さらに多くの労力が必要です。 この理由から、一部の開発者は依存性注入コンテナを厳密に拒否しています。ソフトウェアのパスを非常に混乱させるため、コードナビゲーションの難易度は指数関数的に増加します。 私の質問は次のとおりです。フレームワークまたはパターンがこのように多くのオーバーヘッドを導入する場合、それは価値がありますか?実装パターンが不十分な場合の症状ですか? 開発者は、フラストレーションを乗り越えるために、抽象化がプロジェクトにもたらすものの全体像を調べる必要があると思います。しかし、通常、彼らにその全体像を見せることは困難です。IOCとDIのニーズをTDDで販売できなかったことを知っています。これらの開発者にとって、これらのツールを使用すると、コードの可読性が非常に低下します。

2
依存性注入を使用すると、ソフトウェアエンジニアリングの成果が向上するという証拠はありますか?
その人気にもかかわらず、依存性注入(および/またはDIコンテナーの使用)が、バグ数の削減、保守性の向上、または実際のソフトウェアプロジェクトの開発速度の向上に役立つことを示す経験的証拠はありますか?

1
フレームワークを作成する際の依存性注入/ IoCコンテナープラクティス
多くのプロジェクトで.NetにさまざまなIoCコンテナー(Castle.Windsor、Autofac、MEFなど)を使用しました。彼らは頻繁に虐待される傾向があり、多くの悪い慣行を助長していることがわかりました。 特にプラットフォーム/フレームワークを提供する場合、IoCコンテナーの使用に関する確立されたプラクティスはありますか?フレームワークライターとしての私の目標は、コードをできるだけシンプルで使いやすいものにすることです。オブジェクトを作成するために、10行または2行だけでなく、1行のコードを作成したいです。 たとえば、私が気づいたいくつかのコードの匂いがして、良い提案がありません: コンストラクターの多数のパラメーター(> 5)。サービスの作成は複雑になる傾向があります。すべての依存関係はコンストラクタを介して注入されます-コンポーネントがオプションであるということはめったにありませんが(テスト中を除く)。 プライベートクラスと内部クラスの欠如。これは、C#とSilverlightの使用に関する特定の制限かもしれませんが、どのように解決されるのか興味があります。すべてのクラスがパブリックである場合、フレームワークインターフェイスが何であるかを伝えるのは困難です。それは私がおそらく触れるべきではないプライベートな部分にアクセスできるようにします。 オブジェクトのライフサイクルをIoCコンテナーに結合します。多くの場合、オブジェクトの作成に必要な依存関係を手動で構築することは困難です。オブジェクトのライフサイクルは、IoCフレームワークによって頻繁に管理されます。ほとんどのクラスがシングルトンとして登録されているプロジェクトを見てきました。明示的な制御が得られず、内部の管理も強制されます(上記の点に関連し、すべてのクラスはパブリックであり、それらを注入する必要があります)。 たとえば、.Netフレームワークには多くの静的メソッドがあります。DateTime.UtcNowなど。多くの場合、これが構築パラメーターとしてラップおよびインジェクトされるのを見てきました。 具体的な実装によっては、コードのテストが難しくなります。依存関係を挿入すると、コードが使いにくくなります-特にクラスに多くのパラメーターがある場合。 テスト可能なインターフェイスと使いやすいインターフェイスの両方を提供するにはどうすればよいですか?ベストプラクティスは何ですか?

8
UnitTesting以外の価値がある依存性注入
初期化するいくつかのオブジェクトの異なる実装を使用する必要がないコンストラクターを考えると、DIを使用することは依然として実用的ですか?結局のところ、まだ単体テストが必要な場合があります。 問題のクラスは、コンストラクター内の他のいくつかのクラスを初期化し、使用するクラスは非常に具体的です。別の実装を使用することはありません。インターフェイスにプログラムしようとするのを避けることは正当化されますか?

5
インターフェイスを使用する場合(ユニットテスト、IoC?)
私はここで男子学生の間違いを犯したのではないかと疑い、明確化を求めています。私のソリューションの多くのクラス(C#)-あえて過半数を言う-私は対応するインターフェースを書くことになりました。たとえば、「ICalculator」インターフェースと、それを実装する「Calculator」クラス。ただし、その計算機を別の実装に置き換えることは決してないでしょう。また、これらのクラスのほとんどは、依存関係と同じプロジェクトに存在します。実際に必要なのはinternal、必要なだけですが、publicそれぞれのインターフェイスを実装する副作用として存在することになりました。 すべてのインターフェイスを作成するこのプラクティスは、いくつかの偽りに起因すると思います。 1)元々、ユニットテストモックを作成するにはインターフェイスが必要だと思っていました(私はMoqを使用しています)が、その後、そのメンバーがvirtualであり、パラメーターのないコンストラクターがある場合、クラスをモックできることがわかりました(私が間違っている)。 2)IoCフレームワーク(Castle Windsor)にクラスを登録するにはインターフェースが必要だと当初考えていました。例えば Container.Register(Component.For<ICalculator>().ImplementedBy<Calculator>()... 実際、私はそれ自体に対して具体的な型を登録することができました: Container.Register(Component.For<Calculator>().ImplementedBy<Calculator>()... 3)依存性注入のコンストラクタパラメーターなどのインターフェイスを使用すると、「疎結合」になります。 それで、私はインターフェースに夢中になりましたか?!私は、あなたが「通常」インターフェースを使用するシナリオを知っています。例えば、パブリックAPIを公開したり、「プラグイン可能な」機能のようなもののために。私のソリューションには、そのようなユースケースに適合する少数のクラスがありますが、他のすべてのインターフェースは不要であり、削除する必要があるのでしょうか?上記の3)に関して、これを行う場合、「疎結合」に違反しませんか? 編集:-Moqで遊んでいるだけであり、それらをモックできるようにするには、メソッドがパブリックで仮想であり、パブリックのパラメータレスコンストラクターを必要とするようです。それで、私は内部クラスを持つことができないように見えますか?

2
DDD-Liteは依存性注入のパターン言語ですか?
グレッグヤングの講演7:20でDDD-Liteと呼ばれるものに言及したDDDプロジェクトが失敗する7つの理由に出会った。 要約すると、彼は基本的に、DDDに関連することを何もせずにパターン言語(エンティティ、リポジトリ、値オブジェクト、サービスなど)としてDDDを使用する人もいると言います。彼は、.Netのドメインモデルの60%以上がDDD-Liteであると仮定しています。彼は、DDD-Liteが基本的に依存性注入に関する言語を構築していると考えています。彼は、DDDを完全に実行するか、もっと簡単なことを行うと言います。そうでなければ、彼は、人が良い抽象化を構築するためにこの仕事のすべてを出しているが、本当の利益なしであると主張します。 私はDDDについてあまり知りたいとは思わないので、まだ使用しようとしていません。また、エリック・エヴァンの本も読んでいません。私はずっとエリック・エヴァンスDDD帳から、この主題の使用条件と参照概念に依存性の注入と、多くの、多くの書籍やブログに興味を持って。ここで、DDDの概念に触れました。私がこれを読んでいる本には以下が含まれます: .NETでの依存性注入 Microsoft .Net:企業向けアプリケーションの設計 .NETでのブラウンフィールドアプリケーション開発 依存性注入を実行したい場合、「DDD-Lite」を実行するより簡単な代替手段は何ですか?良い抽象化を構築することは、DDDの概念を「DDD-Lite」の方法で使用しているかどうかに関係なく、非常に役立つように思えます。(Mark Seemannのブログ投稿を参照してください。インターフェースは抽象化ではありません。より良い抽象化に向けて)。依存性注入を行っているすべての人が、本格的なDDDを実行している(または実行する必要がある)ことを信じるのは困難です。グレッグヤングのDDD-Liteについての議論を何らかの形で誤解しましたか?

3
IoCコンテナで販売してください
コードでIoCコンテナを使用することをお勧めします。動機は簡単です。次の依存性注入コードを取得します。 class UnitUnderTest { std::auto_ptr<Dependency> d_; public: UnitUnderTest( std::auto_ptr<Dependency> d = std::auto_ptr<Dependency>(new ConcreteDependency) ) : d_(d) { } }; TEST(UnitUnderTest, Example) { std::auto_ptr<Dependency> dep(new MockDependency); UnitUnderTest uut(dep); //Test here } に: class UnitUnderTest { std::auto_ptr<Dependency> d_; public: UnitUnderTest() { d_.reset(static_cast<Dependency *>(IocContainer::Get("Dependency"))); } }; TEST(UnitUnderTest, Example) { UnitUnderTest uut; //Test here …

5
C ++:クラスはその依存関係を所有または観察する必要がありますか?
class Foobarを使用する(依存する)クラスがあるとしWidgetます。Widget古き良き時代では、woludはのフィールドとして宣言されるFoobarか、多態的な動作が必要な場合はスマートポインターとして宣言され、コンストラクタで初期化されます。 class Foobar { Widget widget; public: Foobar() : widget(blah blah blah) {} // or std::unique_ptr<Widget> widget; public: Foobar() : widget(std::make_unique<Widget>(blah blah blah)) {} (…) }; そして、私たちはすべて準備ができて完了です。残念ながら、今日は、Javaの子供たちはカップルとして、当然、彼らはそれを見たら、私たちを笑う、となりますFoobarとWidget一緒に。解決策は一見シンプルです。依存関係の注入を適用して、Foobarクラスから依存関係を構築します。しかし、その後、C ++は依存関係の所有権について考えるように強制します。3つのソリューションが思い浮かびます。 ユニークなポインター class Foobar { std::unique_ptr<Widget> widget; public: Foobar(std::unique_ptr<Widget> &&w) : widget(w) {} (…) } Foobarそれの唯一の所有権がWidgetそれに渡されると主張する これには次の利点があります。 パフォーマンスへの影響はごくわずかです。 FoobarコントロールのライフタイムがWidgetであるため、安全です。そのため、Widget突然消えることはありません。 Widget漏れることはなく、不要になったときに適切に破壊されます。 ただし、これにはコストがかかります。 Widgetインスタンスの使用方法に制限があります。たとえば、スタックに割り当てられたものWidgetsは使用Widgetできず、共有できません。 …

4
依存関係の注入は、ctorで実行するか、メソッドごとに実行する必要がありますか?
考慮してください: public class CtorInjectionExample { public CtorInjectionExample(ISomeRepository SomeRepositoryIn, IOtherRepository OtherRepositoryIn) { this._someRepository = SomeRepositoryIn; this._otherRepository = OtherRepositoryIn; } public void SomeMethod() { //use this._someRepository } public void OtherMethod() { //use this._otherRepository } } に対して: public class MethodInjectionExample { public MethodInjectionExample() { } public void SomeMethod(ISomeRepository SomeRepositoryIn) { //use SomeRepositoryIn } …

3
依存関係の注入を取得しますが、IoCコンテナーの必要性を理解するのを手伝ってもらえますか?
これが質問のさらに別の繰り返しのように思える場合は申し訳ありませんが、トピックに関する記事を見つけるたびに、それは主にDIとは何かについて話します。だから、私はDIを取得しますが、誰もが入ろうとしているIoCコンテナの必要性を理解しようとしています。IoCコンテナのポイントは、依存関係の具体的な実装を単に「自動解決」することですか?私のクラスにはいくつかの依存関係がない傾向があるかもしれませんし、それが大したことではないのかもしれませんが、コンテナのユーティリティを正しく理解していることを確認したいです。 私は通常、ビジネスロジックを次のようなクラスに分類します。 public class SomeBusinessOperation { private readonly IDataRepository _repository; public SomeBusinessOperation(IDataRespository repository = null) { _repository = repository ?? new ConcreteRepository(); } public SomeType Run(SomeRequestType request) { // do work... var results = _repository.GetThings(request); return results; } } そのため、依存関係は1つだけであり、場合によっては2番目または3番目の依存関係がありますが、それほど頻繁ではありません。そのため、これを呼び出すものはすべて、それ自身のレポを渡すか、デフォルトのレポを使用することができます。 IoCコンテナに関する私の現在の理解に関する限り、コンテナが行うことはIDataRepositoryを解決することだけです。しかし、それがすべてである場合、依存関係が渡されないときに私の操作クラスがすでにフォールバックを定義しているため、大量の値が表示されていません。これは同じフォールバックリポジトリを使用します。レジストリ/工場/コンテナの1つの場所でそのリポジトリを変更できます。それは素晴らしいことですが、それはそれですか?

5
カプセル化を壊さずに依存性注入を使用できますか?
ここに私のソリューションとプロジェクトがあります: BookStore (ソリューション) BookStore.Coupler (プロジェクト) Bootstrapper.cs BookStore.Domain (プロジェクト) CreateBookCommandValidator.cs CompositeValidator.cs IValidate.cs IValidator.cs ICommandHandler.cs BookStore.Infrastructure (プロジェクト) CreateBookCommandHandler.cs ValidationCommandHandlerDecorator.cs BookStore.Web (プロジェクト) Global.asax BookStore.BatchProcesses (プロジェクト) Program.cs Bootstrapper.cs: public static class Bootstrapper.cs { // I'm using SimpleInjector as my DI Container public static void Initialize(Container container) { container.RegisterManyForOpenGeneric(typeof(ICommandHandler<>), typeof(CreateBookCommandHandler).Assembly); container.RegisterDecorator(typeof(ICommandHandler<>), typeof(ValidationCommandHandlerDecorator<>)); container.RegisterManyForOpenGeneric(typeof(IValidate<>), AccessibilityOption.PublicTypesOnly, (serviceType, …

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