dotnet core 的 DI 很好用

所以筆記一下如何在 AWS Lambda 裡面也使用 dotnet core 的 DI

首先先建立一個 interface, 就叫 ITalkService 好了~

namespace AWSLambdaAndDI
/{
    public interface ITalkService
    /{
        string SayHello(string name);
    /}
/}

再寫一個他的實體 TalkService

namespace AWSLambdaAndDI
/{
    public class TalkService : ITalkService
    /{
        public string SayHello(string name)
        /{
            return name + ": hello!";
        /}
    /}
/}

這樣一來我們已經有了 interface 也有實作他的 class,接下來就來看一下如何在一般的 function 使用 dotnet core 的 DI 吧

首先需要使用 dotnet core CLI 來新增 package

dotnet add package Microsoft.Extensions.DependencyInjection

裝完之後就可以看到相依性裡面的套件出現 Microsoft.Extensions.DependencyInjection

我使用了 Visual Studio 來建立了一個 AWS Lambda 的專案,初始的程式碼會長這樣,並將這個 lambda 的 function 相依於前面已經實作好的 interface

using Amazon.Lambda.Core;

// Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class.
[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]

namespace AWSLambdaAndDI
/{
    private readonly ITalkService _talkService;

    public class Function
    /{
        
        /// <summary>
        /// A simple function that takes a string and does a ToUpper
        /// </summary>
        /// <param name="input"></param>
        /// <param name="context"></param>
        /// <returns></returns>
        public string FunctionHandler(string input, ILambdaContext context)
        /{
            return input?.ToUpper();
        /}
    /}
/}

如果要加入 DI ,需要在 constructor 中將需要用的 instance 跟對應到的 interface 進行註冊

constructor 的 code 會長這個樣子

public Function()
/{
  // 建立 DI
  var serviceCollection = new ServiceCollection();
  // 將 TalkService 註冊進 DI
  serviceCollection.AddTransient<ITalkService, TalkService>();
  var serviceProvider = serviceCollection.BuildServiceProvider();
  // 將註冊進 DI 的 talkService 注入 _talkService 這個 interface
  this._talkService = serviceProvider.GetService<ITalkService>();
/}

確定好 talkService 註冊並且注入進 this._talkService 之後,就將 talkService 放進 FunctionHandler 中吧!
目前的 Lambda Function code 就會長這個樣子

using Amazon.Lambda.Core;
using Microsoft.Extensions.DependencyInjection;

// Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class.
[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]

namespace AWSLambdaAndDI
/{
    public class Function
    /{
        private readonly ITalkService _talkService;
        public Function()
        /{
            // 建立 DI
            var serviceCollection = new ServiceCollection();
            // 將 TalkService 註冊進 DI
            serviceCollection.AddTransient<ITalkService, TalkService>();
            var serviceProvider = serviceCollection.BuildServiceProvider();
            // 將註冊進 DI 的 talkService 注入 _talkService 這個 interface
            this._talkService = serviceProvider.GetService<ITalkService>();
        /}

        // 如果需要 unit test 可以利用這個 constructor 來進行 mock talkService
        public Function(ITalkService talkService)
        /{
            this._talkService = talkService;
        /}


        /// <summary>
        /// A simple function that takes a string and does a ToUpper
        /// </summary>
        /// <param name="input"></param>
        /// <param name="context"></param>
        /// <returns></returns>
        public string FunctionHandler(string input, ILambdaContext context)
        /{
            return this._talkService.SayHello(input);
        /}
    /}
/}

接著來使用 Mock Lambda Test Tool 來執行看看吧

以上就可以看到結果囉 “SQZ777: hello!”

如果以上訊息有任何錯誤麻煩告知 感謝各位大大 <(_ _)>