DI（Dependency Injection）のサンプル（コンストラクターインジェクション）


https://qiita.com/takmot/items/ad687ef6f5b058ddda67
前回記事に続いてコンストラクターインジェクションのDIサンプルです。

# ソースコード
ソースコードは前回のものを使用して、IAppService.csだけ追加しています。

├─interfaces
│  ├──IMessageService.cs
│  └──IAppService.cs (追加)
└─services
│  └──MessageService.cs
│
└─application.cs
└─Program.cs

一応全ファイルのコードを載せます。

```C#:IMessageService.cs
namespace di_sample.IF
{
    public interface IMessageService
    {
        string Name { get; }
        string GetMessage();
    }
}
```

```C#:IAppService.cs
namespace di_sample.IF
{
    public interface IAppService
    {
        void greeting();
    }
}
```
サービスは同じインターフェースを継承したものを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;
    }
}
```
以下applicationは、`IMessageService`型サービスのリストをコンストラクタでもらうようにします。
`greeting()`がコールされると、
`IMessageService`型サービスのリストからプロパティNameが"Morning"であるサービスの`GetMessage()`をコールします。

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

namespace di_sample.APP
{
    public class application : IAppService
    {
        IEnumerable<IMessageService> _services;  // IMessageService型のサービスリスト
        public application(IEnumerable<IMessageService> Services) {
            _services = Services;
        }
        public void greeting() {
            writeMessage("Morning");
        }
        private void writeMessage(string name) {
            
            foreach(var service in _services) {
                if (service.Name == name) {        // プロパティでサービスを判定
                    Console.WriteLine(service.GetMessage());
                }
            }
        }
    }
}
```

以下で`IAppService`インターフェースを持つapplicationを追加でDIコンテナに登録しています。
`provider.GetService<IAppService>()`で`IAppService`インターフェースを持つサービスを取り出し、そのサービスの`greeting()`をコールしています。

```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>();    // サービス登録
            services.AddSingleton<IAppService, application>();                  // サービス登録
            
            var provider = services.BuildServiceProvider();
            var service = provider.GetService<IAppService>(); // IAppService型のサービスを取得

            service.greeting();

            Console.ReadLine();
        }
    }
}
```

`provider.GetService<IAppService>()`を実行すると、
applicationのコンストラクタが呼ばれますが、
その前にapplicationのコンストラクタのパラメータ（`IEnumerable<IMessageService> Services`）を取得するため、`MessageServiceMorning`と`MessageServiceAfternoon`のコンストラクタがコールされます。

# 参考記事
https://qiita.com/TsuyoshiUshio@github/items/20412b36fe63f05671c9