[MDP.Net] 依赖注入

MDP.Hosting

MDP.Hosting是一个.NET开发模组,协助开发人员快速建立具有依赖注入的应用系统。提供标签注册、具名实例、具名注入等功能服务,用以简化开发流程并满足多变的商业需求。

说明文件:https://clark159.github.io/MDP.Net/

程式源码:https://github.com/Clark159/MDP.Net/

模组功能

MDP.Hosting-模组功能.png

标签注册

MDP.Hosting扩充.NET Core既有的参数管理,加入ServiceAttribute标签,只要使用标签宣告就可以注册类别(Class)。

// 注册类别
[Service<MessageRepository>(singleton:false)]
public class SqlMessageRepository : MessageRepository
{
  //...
}

- 注册的类别(Class):SqlMessageRepository
- 注册为甚么服务(Service):MessageRepository
- 生成为唯一实例(Instance):singleton=false(false是预设值,可省略)

ServiceAttribute标签:用来宣告注册的类别(Class)、这个类别注册为甚么服务(Service)、以及类别生成的实例(Instance)是否全域唯一。

  • 命名空间:
MDP.Registration
  • 类别定义:
[AttributeUsage(AttributeTargets.Class)]
public sealed class ServiceAttribute<TService> : ServiceAttribute where TService : class

- TService:类别注册为甚么服务(Service)。
  • 建构函式:
public ServiceAttribute(bool singleton = false)

- singleton:类别生成的实例(Instance)是否全域唯一。(false是预设值,可省略)

具名实例

MDP.Hosting里完成注册的类别(Class),在执行阶段会参考Config设定生成实例(Instance)。开发人员可以透过设定Config设定,生成多个实例;而每个实例除了被标记为服务(Service)的Type类型之外,还会被标记为实例(Instance)本身的Name名称。

// 注册类别
namespace MyLab.Module
{
    [Service<MessageRepository>()]
    public class SqlMessageRepository : MessageRepository
    {
        public SqlMessageRepository(string connectionString)
        {
            // ...
        }
    }
}

// Config设定
{
  "MyLab.Module": {
    "SqlMessageRepository": { "ConnectionString" : "Database Connection String"}
  }
}

- 命名空间:MyLab.Module
- 生成实例:SqlMessageRepository
- 生成参数:ConnectionString="Database Connection String"
- 实例Type类型:MessageRepository
- 实例Name名称:SqlMessageRepository

具名注入

被标注Type类型及Name名称的实例(Instance),在系统里就可以被注入使用。预设.NET Core内建的依赖注入,会使用Type类型做为条件取得实例,来提供Typed注入;而MDP.Hosting的依赖注入,则是可以额外使用Name名称做为条件取得实例,来提供Named注入。(注:.NET8将会支援Named注入)

Typed注入范例:ASP.NET Core生成HomeController的时候,预设取得Type类型被标注为MessageRepository的实例来注入。

// 注册类别
namespace MyLab.Module
{
    [Service<MessageRepository>()]
    public class SqlMessageRepository : MessageRepository
    {
        //...
    }
}

// Config设定
{
  "MyLab.Module": {
    "SqlMessageRepository": {}
  }
}

// 服务注入
public class HomeController : Controller
{
	public HomeController(MessageRepository messageRepository)
	{
	    // ...
	}
}

- 命名空间:MyLab.Module
- 生成实例:SqlMessageRepository
- 实例Type类型:MessageRepository
- 实例Name名称:SqlMessageRepository

Named注入范例:MDP.Hosting生成MessageContext的时候,参考Config设定("messageRepository": "SqlMessageRepository"),取得Name名称被标注为SqlMessageRepository的实例来注入。

// 注册类别
namespace MyLab.Module
{
	[Service<MessageContext>(singleton: true)]
	public class MessageContext
	{
		public MessageContext(MessageRepository messageRepository)
		{
			// ...
		}
	}

	[Service<MessageRepository>()]
	public class SqlMessageRepository : MessageRepository
	{
 	   //...
	}
}

// Config设定
{
  "MyLab.Module": {
    "MessageContext": {
	  "messageRepository": "SqlMessageRepository"
	},
    "SqlMessageRepository": {}
  }
}

- 命名空间:MyLab.Module
- 生成实例:SqlMessageRepository
- 实例Type类型:MessageRepository
- 实例Name名称:SqlMessageRepository

模组使用

加入模组

MDP.Hosting预设内建在MDP.Net专案范本内,依照下列操作步骤,即可建立包含MDP.Hosting模组的专案。

  • 在命令提示字元输入下列指令,使用MDP.Net专案范本建立专案。
// 建立API服务、Web站台
dotnet new install MDP.WebApp
dotnet new MDP.WebApp -n WebApplication1

// 建立Console程式
dotnet new install MDP.ConsoleApp
dotnet new MDP.ConsoleApp -n ConsoleApp1

使用ServiceAttribute

建立包含MDP.Hosting模组的专案之后,就可以使用ServiceAttribute标签,透过标签宣告来注册类别(Class)。

// 注册类别
namespace MyLab.Module
{
    [Service<MessageRepository>()]
    public class SqlMessageRepository : MessageRepository
    {
        public SqlMessageRepository(string connectionString)
        {
            // ...
        }
    }
}

设定参数

MDP.Hosting里完成注册的类别(Class),开发人员可以透过设定Config设定生成实例(Instance)。

// Config设定
{
  "MyLab.Module": {
    "SqlMessageRepository": { "ConnectionString" : "Database Connection String"}
  }
}

- 命名空间:MyLab.Module
- 生成实例:SqlMessageRepository
- 生成参数:ConnectionString="Database Connection String"
- 实例Type类型:MessageRepository
- 实例Name名称:SqlMessageRepository

模组范例

专案开发过程,在开发/测试/正式三个执行环境,常常需要各自使用不同资料来源、或是使用不同连线字串。例如:开发环境使用Mock资料来源(假资料)、测试环境使用SQL资料来源(连线至测试资料库)、正式环境使用SQL资料来源(连线至正式资料库)。本篇范例协助开发人员使用MDP.Hosting,逐步完成必要的设计和实作。

操作步骤

1.开启命令提示字元,输入下列指令。用以安装MDP.WebApp范本、并且建立一个名为WebApplication1的Web站台。

dotnet new install MDP.WebApp
dotnet new MDP.WebApp -n WebApplication1

2.使用Visual Studio开启WebApplication1专案。于专案内加入Modules\MessageContext.cs、Modules\MessageRepository.cs,并使用标签宣告来注册MessageContext。

using MDP.Registration;

namespace WebApplication1
{
    [Service<MessageContext>(singleton: true)]
    public class MessageContext
    {
        // Fields
        private readonly MessageRepository _messageRepository = null;


        // Constructors
        public MessageContext(MessageRepository messageRepository)
        {
            // Default
            _messageRepository = messageRepository;
        }


        // Methods
        public string GetValue()
        {
            // Return
            return _messageRepository.GetValue();
        }
    }
}
namespace WebApplication1
{
    public interface MessageRepository
    {
        // Methods
        string GetValue();
    }
}

3.于专案内加入Modules\SqlMessageRepository.cs、Modules\MockMessageRepository.cs,并使用标签宣告来注册类别为MessageRepository。

using MDP.Registration;

namespace WebApplication1
{
    [Service<MessageRepository>()]
    public class SqlMessageRepository : MessageRepository
    {
        // Fields
        private readonly string _connectionString;


        // Constructors
        public SqlMessageRepository(string connectionString)
        {
            // Default
            _connectionString = connectionString;
        }


        // Methods
        public string GetValue()
        {
            // Return
            return "Hello World By " + _connectionString;
        }
    }
}
using MDP.Registration;

namespace WebApplication1
{
    [Service<MessageRepository>()]
    public class MockMessageRepository : MessageRepository
    {
        // Methods
        public string GetValue()
        {
            // Return
            return "Hello World By Mock Source";
        }
    }
}

4.改写专案内的Controllers\HomeController.cs、Views\Home\Index.cshtml,注入并使用MessageContext。

using System;
using Microsoft.AspNetCore.Mvc;

namespace WebApplication1
{
    public class HomeController : Controller
    {
        // Fields
        private readonly MessageContext _messageContext = null;


        // Constructors
        public HomeController(MessageContext messageContext)
        {
            // Default
            _messageContext = messageContext;
        }


        // Methods
        public ActionResult Index()
        {
            // ViewBag
            this.ViewBag.Message = _messageContext.GetValue();

            // Return
            return View();
        }
    }
}
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>WebApplication1</title>
</head>
<body>

    <!--Title-->
    <h2>WebApplication1</h2>
    <hr />

    <!--Message-->
    <h3>@ViewBag.Message</h3>

</body>
</html>

5.于专案内加入下列三个Config设定档,用来定义开发/测试/正式三个执行环境,各自使用不同资料来源、使用不同连线字串。

  • 开发环境:\config\Development\appsettings.json,设定为MessageContext具名注入MockMessageRepository。(Mock资料来源)
{
  "WebApplication1": {
    "MessageContext": {
      "MessageRepository": "MockMessageRepository"
    },
    "MockMessageRepository": {}
  }
}
  • 测试环境:\config\Staging\appsettings.json,设定为MessageContext具名注入SqlMessageRepository,并且设定连线至Staging Database。(SQL资料来源)
{
  "WebApplication1": {
    "MessageContext": {
      "MessageRepository": "SqlMessageRepository"
    },
    "SqlMessageRepository": { "connectionString": "Staging Database" }
  }
}
  • 正式环境:\config\Production\appsettings.json,设定为MessageContext具名注入SqlMessageRepository,并且设定连线至Production Database。(SQL资料来源)
{
  "WebApplication1": {
    "MessageContext": {
      "MessageRepository": "SqlMessageRepository"
    },
    "SqlMessageRepository": { "connectionString": "Production Database" }
  }
}

6.执行专案,于开启的Browser视窗内,可以看到系统依照开发环境:\config\Development\appsettings.json的设定执行,于画面显示MockMessageRepository回传的Hello World By Mock Source。

01.执行结果01.png

7.改写专案内的启动档 \Properties\launchSettings.json,将ASPNETCORE_ENVIRONMENT的内容改为Staging。

{
  "profiles": {
    "WebApplication1": {
      "commandName": "Project",
      "dotnetRunMessages": true,
      "launchBrowser": true,
      "applicationUrl": "https://localhost:7146;http://localhost:5257",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Staging"
      }
    }
  }
}

8.重建并执行专案,于开启的Browser视窗内,可以看到系统依照测试环境:\config\Staging\appsettings.json的设定执行,于画面显示SqlMessageRepository回传的Hello World By Staging Database。

01.执行结果02.png

9.最后将ASPNETCORE_ENVIRONMENT的内容改为Production,重建并执行专案,于开启的Browser视窗内,可以看到系统依照正式环境:\config\Production\appsettings.json的设定执行,于画面显示SqlMessageRepository回传的Hello World By Production Database。

01.执行结果03.png

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章