Unityの最初のステップ:DI / IoC&AOP

はじめに



IoC、DI、AoPなどの言葉を聞いたことがあるが、これらの用語を明確に理解していない場合は、この記事がMicrosoft Unityコンテナーでの作業の例によってそれらに侵入するのに役立つことを願っています。



それでは、理論を始めましょう:



制御の反転(IoC)および依存性注入(DI)



IoCの定義については、 Wikipediaを参照してください



Inversion of Control(IoC)はオブジェクト指向プログラミングの重要な原則であり、コンピュータープログラムの接続性を減らすために使用されます。



IoCはDependency Injection Principleとしても知られています。 依存性注入は、ほぼすべてのフレームワークで使用されます。 Smalltalk、C ++、Java、または.NETプラットフォーム言語などのオブジェクト指向プログラミング言語を使用するプログラマーによって使用されます。





*すぐにIoCにロシア語の翻訳を使用したくないという予約をしたかったのですが、もし彼らが私にそうするように強制した場合、それを「コントロールインバージョン」として使用します



DIの定義については、 ウィキペディアにも目を向けます。



依存性注入とは、ソフトウェアコンポーネントに外部依存性を提供するプロセスを指し、「制御の反転」の特定の形式であり、通信の順序を変更することが必要な依存性を取得する方法です。





アプリケーションオブジェクトがどれだけ密接にリンクされているかを判断する典型的な例は、サブジェクトエリアから新しいアプリケーションにクラスをコピーし、それが機能しない場合は実行してみてから、関連するクラスをコピーすることです。 通常、これらの操作の結果、古いアプリケーションは新しいアプリケーションにほぼ完全にコピーされます。



あるオブジェクトと別のオブジェクトの依存関係の問題を解決するために、通常、必要なオブジェクトの作成/取得を担当するのは依存関係を持つオブジェクトです( ところで、ファクトリ、レジストリなどのテンプレートに注意を向けたいと思います)。



擬似コードIoCおよびDIを使用した実装の例は数多くあります。この点については、記事が大きくなることを望んでいませんが、実際の使用よりも理解を深めることはほとんどできません。



ここに.NET DI / IoCコンテナリストすると便利だと思います







アスペクト指向プログラミング(AoP)





私は細心の注意を払ったウィキペディアのファンです:



アスペクト指向プログラミング(AOP)は、機能、特にエンドツーエンド機能を分割して、プログラムをモジュールに分解するという考え方に基づいたプログラミングパラダイムです。





アスペクト指向プログラミング(AOP)は、アプリケーションで記述されたコードの量を減らすために、OOPを支援することも目的としていることを付け加えておきます。



ほとんどの場合、AOPの使用は、ロギング、キャッシュ、検証、アクセス制御などの日常的なタスクの実装に限定されます。 この問題は、ビジネスオブジェクトをDecoratorテンプレート( ロシア語 )で囲むことで解決できると主張し、言うことができますが、実際には、コンシューマコードを変更する必要があり、AOPを使用すると簡単に自然にこれを行うことができます。



有名なフレームワーク:







Microsoft Enterprise Libraryについて



ご存知のように、Microsoftは2008年10月にEnterprise Libraryバージョンを4.1にUnity Application Blockコンポーネントの1つをバージョン1.2にそれぞれ更新しました。 Microsoft Enterprise Libraryは、 パターンとプラクティスグループによって開発されています 。 Microsoft Enterprise Libraryは、開発者が一般的なルーチンタスクを完了できるように設計された機能ブロックのセットです。 ファンクションブロックは一種のマニュアルであり、その一部として提供されるソースコードは、開発者がニーズに応じて「そのまま」使用、拡張、または変更できます。 Microsoft Enterprise Libraryは、次のブロックで構成されています。







Unity Application Blockについて





拡張機能によるインターセプトの実装と同じ方法で、コンストラクター、プロパティ、およびメソッド呼び出しに依存関係を注入することをサポートする、軽量で拡張可能な依存性注入コンテナー。 エンタープライズライブラリ(EntLib)と一緒に使用して、独自のオブジェクトとエンタープライズライブラリの両方のオブジェクトを生成できます。 ただし、Unity Application Blockは他のEntLib機能ブロックとはいくつかの重要な点で異なります。







待望のアクション





必要条件





以下の例が機能するには、次のものが必要です。



  1. .NET Framework 3.5 SP1がインストールされている
  2. お気に入りのIDE(メモ帳.. Visual Studio 2008 SP1
  3. Unityによってインストールされます
  4. 15〜20分と少し関心




プロセス





開始するには、UnityInAction1というConsoleApplicationを作成します。



次に、次のアセンブリへのリンクを追加します。







アプリケーションでILoggerインターフェイスを作成しましょう。



namespace UnityInAction1 { interface ILogger { void Write( string msg); } }

* This source code was highlighted with Source Code Highlighter .




  1. namespace UnityInAction1 { interface ILogger { void Write( string msg); } }

    * This source code was highlighted with Source Code Highlighter .




  2. namespace UnityInAction1 { interface ILogger { void Write( string msg); } }

    * This source code was highlighted with Source Code Highlighter .




  3. namespace UnityInAction1 { interface ILogger { void Write( string msg); } }

    * This source code was highlighted with Source Code Highlighter .




  4. namespace UnityInAction1 { interface ILogger { void Write( string msg); } }

    * This source code was highlighted with Source Code Highlighter .




  5. namespace UnityInAction1 { interface ILogger { void Write( string msg); } }

    * This source code was highlighted with Source Code Highlighter .




  6. namespace UnityInAction1 { interface ILogger { void Write( string msg); } }

    * This source code was highlighted with Source Code Highlighter .




  7. namespace UnityInAction1 { interface ILogger { void Write( string msg); } }

    * This source code was highlighted with Source Code Highlighter .




namespace UnityInAction1 { interface ILogger { void Write( string msg); } }

* This source code was highlighted with Source Code Highlighter .








次に、Loggerクラスに実装します。







  1. システムを使用して ;
  2. 名前空間 UnityInAction1
  3. {
  4. クラス Logger:ILogger
  5. {
  6. #region ILoggerメンバー
  7. public void Write( string msg)
  8. {
  9. Console .WriteLine();
  10. Console .WriteLine( "***ロガー***" );
  11. Console .WriteLine( String .Format( "message {0}" 、msg));
  12. }
  13. #endregion
  14. }
  15. }


*このソースコードは、 ソースコードハイライターで強調表示されました。




これは通常のアプリケーションです。







  1. システムを使用して ;
  2. 名前空間 UnityInAction1
  3. {
  4. クラスプログラム
  5. {
  6. static void Main( string [] args)
  7. {
  8. ILoggerロガー= 新しいロガー();
  9. logger.Write( "マイメッセージ" );
  10. Console .ReadKey();
  11. }
  12. }
  13. }


*このソースコードは、 ソースコードハイライターで強調表示されました。




ただし、IoC / DIアプローチの観点からは、これは私たちにはあまり適していません。これに関連して、ロガーをコンテナに配置します(たとえば、交換するために[また、カバレッジ全体ではなく、コンテナ構成の場所でのみ交換する必要がありますコード、通常は発生します]テスト時のスタブです):







  1. システムを使用して ;
  2. Microsoft.Practices.Unity を使用します。
  3. 名前空間 UnityInAction1
  4. {
  5. クラスプログラム
  6. {
  7. static void Main( string [] args)
  8. {
  9. IUnityContainer container = new UnityContainer();
  10. container.RegisterType <ILogger、Logger>( new ContainerControlledLifetimeManager());
  11. var logger = container.Resolve <ILogger>();
  12. logger.Write( "マイメッセージ" );
  13. Console .ReadKey();
  14. }
  15. }
  16. }


*このソースコードは、 ソースコードハイライターで強調表示されました。




さて、この例を開始するのに十分だと思います。



ここで、このインターフェイスのすべての実装に対してILogger.Write()メソッドの実行時間を測定する要件を追加します。OOPを使用すると、この条件を実装することがより難しくなることは明らかです。したがって、AOPの観点からこの例を見ていきます。 まず、 新しい .NET 属性を導入して、ILoggerの説明を少し再定義しましょう。







  1. 名前空間 UnityInAction1
  2. {
  3. インターフェース ILogger
  4. {
  5. [ストップウォッチ]
  6. void Write( string msg);
  7. }
  8. }


*このソースコードは、 ソースコードハイライターで強調表示されました。




ストップウォッチ属性の説明:







  1. システムを使用して ;
  2. Microsoft.Practices.Unity.InterceptionExtension を使用します。
  3. 名前空間 UnityInAction1
  4. {
  5. クラス Stopwatch:HandlerAttribute
  6. {
  7. パブリック オーバーライド ICallHandler CreateHandler(Microsoft.Practices.Unity.IUnityContainerコンテナー)
  8. {
  9. 新しい StopwatchCallHandler()を返します。
  10. }
  11. }
  12. パブリック クラス StopwatchCallHandler:ICallHandler
  13. {
  14. public int Order { get ; セット ;}
  15. public StopwatchCallHandler(): this (0){}
  16. パブリック StopwatchCallHandler( int順序)
  17. {
  18. 注文=注文;
  19. }
  20. #region ICallHandlerメンバー
  21. public IMethodReturn Invoke(IMethodInvocation入力、GetNextHandlerDelegate getNext)
  22. {
  23. System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
  24. sw.Start();
  25. var result = getNext()。Invoke(input、getNext);
  26. sw.Stop();
  27. Console .WriteLine();
  28. Console .WriteLine( String .Format( " Elapsed time {0} ms" 、sw.ElapsedMilliseconds));
  29. 結果を返す ;
  30. }
  31. #endregion
  32. }
  33. }


*このソースコードは、 ソースコードハイライターで強調表示されました。




さて、コンテナの拡張機能を追加します。







  1. システムを使用して ;
  2. Microsoft.Practices.Unity を使用します。
  3. Microsoft.Practices.Unity.InterceptionExtension を使用します。
  4. 名前空間 UnityInAction1
  5. {
  6. クラスプログラム
  7. {
  8. static void Main( string [] args)
  9. {
  10. IUnityContainer container = new UnityContainer();
  11. container.RegisterType <ILogger、Logger>( new ContainerControlledLifetimeManager());
  12. container.AddNewExtension <Interception>();
  13. container.Configure <Interception>()
  14. .SetInterceptorFor <ILogger>( new TransparentProxyInterceptor());
  15. var logger = container.Resolve <ILogger>();
  16. logger.Write( "マイメッセージ" );
  17. Console .ReadKey();
  18. }
  19. }
  20. }


*このソースコードは、 ソースコードハイライターで強調表示されました。




さて、ILogger.Write()の各実装は、このメソッドの実行時間の測定値を出力します、それは素晴らしいことではありませんか?



素材









結論として





この記事が、品質コードの分野でのあなたの研究にとって良いスタートを切ることを願っています。



PSこれはハブに関する私の最初の投稿なので、 私自身について少し説明します。私の関心の範囲は非常に広く、技術的なコンポーネントは.NET開発(ASP.NET、Sharepoint、WWF、Silverlight)、開発方法(Agile、Scrum、XP)、開発テクニック(TDD、DDD、MDA、AOP)。



All Articles