DI（Dependency Injection）のサンプル

DI関連の記事をいくつか読んで、大体の使い方はわかったが、
自分で書かないと腑に落ちない部分もあったため、書いてみたサンプルです。
そのためDIの説明的なものは特に触れません。

以下コンストラクターインジェクションのサンプル
https://qiita.com/takmot/items/babc1590a3f9789553a4

# ソースコード

ベースは`dotnet new console`で生成したプロジェクトになります。
以下のようにinterfacesフォルダにインターフェースクラスを定義したファイルを、
servicesフォルダにインターフェースを継承したサービスクラスを定義したファイルを作成しています。

├─interfaces 
│   &emsp;└──IMessageService.cs
└─services
│   &emsp;└──MessageService.cs
│
└─application.cs
└─Program.cs

```C#:IMessageService.cs
namespace di_sample.IF
{
    public interface IMessageService
    {
        string Name { get; }
        string GetMessage();
    }
}
```
サービスは同じインターフェースを継承したものを2個作っています。
サービス区別用にプロパティにNameを持っています。

```C#:MessageService.cs
using di_sample.IF;
public class MessageServiceMorning : IMessageService
{
    public string Name { get; } = "Morning";
    private string message = "";
    public MessageServiceMorning()
    {
        message = "Good morning.";
    }
    public string GetMessage()
    {
        return message;
    }
}
public class MessageServiceAfternoon : IMessageService
{
    public string Name { get; } = "Afternoon";
    private string message = "";
    public MessageServiceAfternoon()
    {
        message = "Good afternoon.";
    }
    public string GetMessage()
    {
        return message;
    }
}
```
以下でDIコンテナを生成し、IMessageServiceインターフェースを持つクラス2つを登録します。

```C#:Program.cs
using System;
using Microsoft.Extensions.DependencyInjection;
using di_sample.APP;
using di_sample.IF;

namespace di_sample
{
    class Program
    {
        static void Main(string[] args)
        {

            var services = new ServiceCollection(); // DIコンテナ
            services.AddSingleton<IMessageService, MessageServiceAfternoon>();  // サービス登録
            services.AddSingleton<IMessageService, MessageServiceMorning>();    // サービス登録
            
            var app = new application(services);

            Console.ReadLine();
        }
    }
}
```
以下で、サービスの取り出し、サービスの区別、サービスの持つ関数コールを行います。

```C#
using System;
using System.Collections.Generic;
using Microsoft.Extensions.DependencyInjection;
using di_sample.IF;

namespace di_sample.APP
{
    public class application
    {
        IEnumerable<IMessageService> Services;  // IMessageService型のサービスリスト
        public application(ServiceCollection services) {
            var provider = services.BuildServiceProvider();
            Services = provider.GetServices<IMessageService>(); // IMessageService型のサービスを取得

            writeMessage("Morning");
        }
        private void writeMessage(string name) {
            
            foreach(var service in Services) {
                if (service.Name == name) {        // プロパティでサービスを判定
                    Console.WriteLine(service.GetMessage());
                }
            }
        }
    }
}
```

ちなみに、サービス（`MessageServiceMorning`, `MessageServiceAfternoon`）のコンストラクタは、
サービスを取り出すタイミング（`Services = provider.GetServices<IMessageService>();`）でコールされます。

`using Microsoft.Extensions.DependencyInjection;`
にはパッケージの追加が必要です。
https://www.nuget.org/packages/Microsoft.Extensions.DependencyInjection

```
dotnet add package Microsoft.Extensions.DependencyInjection --version 3.1.8
```

コンストラクターインジェクションを使用したサンプルも書こうと思います。

# 参考記事

https://qiita.com/TsuyoshiUshio@github/items/20412b36fe63f05671c9
https://qiita.com/saeki4n/items/22a276dcac9ef537ee25