概要
C#でDIコンテナを使用する方法について解説します。
DIコンテナは、MicrosoftのUnityを使用します。
DIコンテナの説明については、割愛します。
環境
本記事では、以下の環境で開発を行いました。
- Visual Studio 2019
- .NET Framework 4.6.1
- コンソールアプリ、クラスライブラリ
DIコンテナのインストール
テスト用のソリューション及びプロジェクトを作成します。
DIContainerTestAppはコンソールアプリ、DITestLibraryはクラスライブラリで作成します。
DITestLibraryに、以下のインターフェースを追加します。
namespace DITestLibrary { public interface IDevice { string Name { get; set; } string GetMessage(); } }
DITestLibraryに、以下のクラスを追加します。
namespace DITestLibrary { public class Device : IDevice { public string Name { get; set; } public string GetMessage() { return "Called Device GetMessage methods"; } } }
NuGetよりUnityをインストールします。
また、設定ファイルから依存性注入を行う形式も実施しますので、Unity.Configurationもインストールします。
ここまでで事前準備は完了です。
DIコンテナを使ってみる
インターフェースとクラスの型を登録し、インターフェースを取得する
ここでは、IDeviceとそれを継承したDeviceクラスを登録しておき、インターフェースを指定し取得する方法を記載します。
diContainer.RegisterType<IDevice, Device>();で、IDeviceとDeviceのリレーションを登録します。
IDevice device = diContainer.Resolve<IDevice>();で、DIコンテナにて、Deviceクラスがインスタンス化され、IDeviceのインターフェースの形で取得することができます。これにより、使用する側は、実際のクラスを意識することなく、インターフェースだけを意識すればよいことになります。
using DITestLibrary; using System; using Unity; namespace DIContainerTestApp { class Program { static void Main(string[] args) { UnityContainer diContainer = new UnityContainer(); diContainer.RegisterType<IDevice, Device>(); IDevice device = diContainer.Resolve<IDevice>(); Console.WriteLine(device.GetMessage()); // >> Called Device GetMessage methods } } }
シングルトンで登録し、取得する
RegisterTypeにて、TypeLifetime.Singletonを指定します。
これにより、Resolve時に取得するインスタンスをシングルトンとすることができます。
using DITestLibrary; using Microsoft.Practices.Unity.Configuration; using System; using Unity; namespace DIContainerTestApp { class Program { static void Main(string[] args) { UnityContainer diContainer = new UnityContainer(); diContainer.RegisterType<IDevice, Device>(TypeLifetime.Singleton); IDevice deviceA = diContainer.Resolve<IDevice>(); deviceA.Name = "device name"; IDevice deviceB = diContainer.Resolve<IDevice>(); Console.WriteLine(deviceA.Name); // >> device name Console.WriteLine(deviceB.Name); // >> device name } } }
設定ファイルでインターフェースとクラスを指定して、依存性注入してみる
設定ファイル(App.config)に、インターフェースとクラスを指定して、依存性注入する方法を紹介します。
App.configに以下の設定をします。
<?xml version="1.0" encoding="utf-8" ?> <configuration> <configSections> <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Unity.Configuration"/> </configSections> <startup> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" /> </startup> <unity xmlns="http://schemas.microsoft.com/practices/2010/unity"> <namespace name="DITestLibrary" /> <assembly name="DITestLibrary" /> <container> <register type="IDevice" mapTo="Device" /> </container> </unity> </configuration>
Program.csに以下のコードを記載して実行します。
LoadConfigurationメソッドを呼び出すことにより、DIコンテナが設定ファイルを読み込み、RegisiterInstanceを呼び出すことなく、依存性注入をすることができます。
using DITestLibrary; using Microsoft.Practices.Unity.Configuration; using System; using Unity; namespace DIContainerTestApp { class Program { static void Main(string[] args) { UnityContainer diContainer = new UnityContainer(); diContainer.LoadConfiguration(); IDevice device = diContainer.Resolve(); Console.WriteLine(device.GetMessage()); // >> Called Device GetMessage methods } } }
コメント