依存性注入はどのようにして言語に統合できるでしょうか?[閉まっている]


10

依存性注入をC#のような言語に直接統合する方法を少し考えてきました。私はあなたの意見を聞きたいと思う潜在的な解決策を考え出しました。私は多くの依存関係注入フレームワークを使用していないので、見落としているものがあるかもしれません

とにかく、キーワードを使用してプロパティを「注入可能」として宣言できるようにするという考えです。オブジェクトがインスタンス化され、そのプロパティがコンストラクターまたはオブジェクト初期化子を介して初期化されない場合、オブジェクトはいくつかのグローバルサービスからそのプロパティタイプのインスタンスを要求します。

同様に、さまざまなタイプのハンドラーをそのサービスに登録して、注入されたプロパティタイプをインスタンス化できるようにします。

この種のアーキテクチャーIMOを使用する利点は、かなり柔軟で使いやすいことです。欠点は、インジェクションを持つクラスを開始するたびにシングルトンへのコールアウトを実行するオーバーヘッドがある可能性があることです。

繰り返しになりますが、これは、高性能ソリューションで頻繁にインスタンス化されるクラスの問題にすぎないため、それほど問題にはなりません。おそらく、それらのインスタンスで何らかのファクトリを使用できます。

考え、問題、質問、より良いアイデア?

コード

public class SomeClass
{

  public SomeClass()
  {
     //implicit behavior if Animal is not set in constructor or initializer
    this.Animal =  GlobalInjector.Get(this,typeof(Mammal))

  }

  public injectable Mammal Animal  
  {
   get;
   set;
  }
}


 GlobalInjector.Register(typeof(Mammal), () => return new Mammal(someParameter));

DIに慣れていない私たちのために、疑似コードの例を挙げていただけませんか?PS。多分、DIに関する私の質問にも答えられますか?:)
スティーブン

2
わかりません。キーワードの代わりに、グローバルDIコンテナーと '[Injectable]'属性を使用して、これらすべてを取得できます。
nikie、2011年

こんにちは、私はあなたの質問にDIについて少し書いてみましたが、それが答えかどうかは
わかり

nikie:基礎となるロジックが健全であるかどうかわからええ、私はあなたがさまざまな方法で実際のメカニズムを実装することができ、私はより多くの興味を推測
Homde

では、追加のキーワードを除いて、これと既存のIoCの違いは何ですか?
マシューホワイト、2011年

回答:


7

言語に属するものとそうでないものがあります。ずっと前にCは、IOはコンピューティングモデルの外部にあり、関数ライブラリで実装できるため、IOは言語に属していないことを認識していました。

依存性注入はそのようなものです。言語の外部にあり、適切なフレームワークで実装できます。

現代の言語の問題の1つは、彼らがやりすぎることです。プログラマーがより単純な言語に逃げると、最終的にそれらの言語は自重で崩壊します。


理論的には同意します。言語が肥大化しない限り、すべての関数がその言語の特徴である言語を作成することはできません。ただし、より優れたコードを作成するのに役立つ新しいより高い抽象化の余地は常にあります。おそらく、依存性注入自体は解決が必要な問題ではありませんが、それが取り組む問題、つまり依存関係を減らすのをより簡単にする方法です。これはそれを行う最善の方法ではないかもしれません:)
Homde

5

必要ありません

私が使用した中で最高のDIフレームワークについて私が最も気に入っていることの1つは、トップレベルの構成コードが、DIについて知る必要があるコードの唯一の部分であることです。自動配線はコンテナおよび設定/「モジュール読み込み」レベルで行われ、アプリケーションコードは完全に気付かない可能性があります。

これは、属性、マジックストリング、規則がないことを意味します。各コードは、コンストラクター(/ properties / methods)でコードを受け入れることを知っているだけで、それだけです。

このような設計では、依存性注入をサポートするために言語を変更する必要はありません。

潜在的に危険です

言語統合された依存性注入システムについて私が最も恐れていることは、他の実装に対する障壁を引き上げることですが、それでもおそらくいくつかの側面でコーナーに自分自身を描くでしょう。

コーナーに自分自身をペイントするいくつかの方法:

  • XMLベースの構成のみ、またはコードベースの構成のみをサポート
  • Factory設計パターンを完全にサポートできない(一時的なコンポーネントだけでなく、実行時に生成されるコンポーネント)
  • どういうわけかコードを変更して依存関係注入を使用せざるを得なくなり、ユニットテスト用にクラスを単純にインスタンス化できなかった
  • カスタムライフサイクルをサポートしない
  • 拡張できない
  • さらにカスタマイズが必要な場合に交換できない
  • 私たちの.NetユーザーはDIを十分に長く使用していないため、まだ理解していない方法で壊れている

4

.NET 4に付属するManaged Extensibility Frameworkを見たことがありますか?これが私がいくつかの例で書いた記事です。基本的には、.NETに組み込まれた依存性注入の一種であり、実行時の検出機能が追加されています。

プロパティインジェクションは次のようになります。

class Program
{
    [Import]
    public IMessageSender MessageSender { get; set; }
}

コンストラクターの注入は次のようになります。

class Program
{
    [ImportingConstructor]
    public Program(IMessageSender messageSender) 
    {
    ...
    }
}

フィールドをインポートしたり、オプションのインポートを行ったり、メタデータを使用したレイジーインポートを含めてサービスのコレクションをインポートしたりして、インスタンス化する適切なサービスを検索できます。実行時に再インポートして、新しい拡張機能を探すこともできます。


MEFはプラグイン関連のものには本当に
便利ですが

1
@MKO-不足しているものについて詳しく説明できますか?私は、グレンブロックがMEF すべてのDIフレームワークに取って代わるものではないことを人々に安心させるために競争するすべての記事を知っていますが、詳細を見ると、他の何よりも政治的声明のほうがはっきりしています。ただし、他のDIフレームワークと比較してMEFに欠けている機能の良いリストを提供できれば、それは人々が情報に基づいた決定を行うのに役立ちます。さらに、問題はC#のDIフレームワークに関するものであり、MEFは明らかに.NETフレームワークのDIコンテナーです。
スコットホイットロック

2
  1. IMHOがトリッキーなビットである構成メカニズムを実際には説明しません。1つのスレッドで実行されているすべてのコードでDB接続Aを使用し、他のスレッド接続Bですべてのコードを使用するにはどうすればよいですか?現在ログインしているユーザーはアクセスできないため、特定のリソースの注入をどのようにブロックしますか?
  2. グローバルインジェクターを使用しないでください。グローバルなものは一切使用しないでください。グローバル変数を使用することもできます。いいえ、グローバルの代わりにシングルトンや「静的」などのOOPピークを使用しても、グローバルな性質は変わりません。
  3. 動的スコープのコンテナーについて考えてみましょう。字句スコープが動的スコープに勝っているのは当然ですが、動的スコープはグローバルスコープの代わりになると思います。差分継承は(プロトタイプベースの継承のように)優れた実装です。
  4. 言語で義務付けられたDIメカニズムは本当にシンプルである必要があると私は信じています。C#やJavaの標準であるエンタープライズ的なものはどれもありません。シンプルな構成レイヤーを上に配置した動的スコープメカニズムでうまくいく場合があります。エンタープライズソリューションは、サードパーティによって上に重ねることができます。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.