DependencyInjection组件的综合应用案例(3)

发布时间 2023-12-18 17:48:34作者: 落花流水1173

目的:通过一个较综合的案例演示依赖注入的使用

需求:有配置服务、日志服务,然后再开发一个邮件发送器服务。

           可以通过配置服务来从文件、环境变量、数据库等地方读取配置,

           可以通过日志服务来将程序运行过程中的日志信息写入文件、控制台、数据库等。

说明:配置服务和日志服务.net中都有现有的框架,这篇文章只是为了演示依赖注入重写写了这两个服务,没有实际作用,邮件发送也只是用控制台来显示,不是实际的发送邮件

项目分3个服务类库项目和1个应用程序项目,如下

1、配置服务项目

 /// <summary>
 /// 配置提供者
 /// </summary>
 public interface IConfigProvider
 {
     /// <summary>
     /// 根据名称获取值
     /// </summary>
     /// <param name="Name"></param>
     /// <returns></returns>
     string GetValue(string Name);
 }

 class EnvVarConfigProvider : IConfigProvider
{
    public string GetValue(string Name)
    {
       return Environment.GetEnvironmentVariable(Name);
    }
}

public static class ConfigProviderExtensions
{

    public static void AddEnvVarConfig(this IServiceCollection services)
    {
        services.AddScoped<IConfigProvider, EnvVarConfigProvider>();
    }

}

AddEnvVarConfig是一个扩展方法,使用扩展方法进行注册的好处是:应用者无需关注具体的实现类,使用时只需service.AddEnvVarConfig()即可,所以EnvVarConfigProvider类不需public

 2、日志服务项目

/// <summary>
/// 日志提供者
/// </summary>
public interface ILogProvider
{
    /// <summary>
    /// 记录错误信息
    /// </summary>
    /// <param name="mes"></param>
    void LogError(string mes);
    /// <summary>
    /// 记录普通信息
    /// </summary>
    /// <param name="mes"></param>
    void LogInfo(string mes);
}


    /// <summary>
    /// 控制台日志提供者
    /// </summary>
     class ConsoleLogProvider : ILogProvider
    {
        public void LogError(string mes)
        {
            Console.WriteLine($"Error:{mes}");
        }

        public void LogInfo(string mes)
        {
            Console.WriteLine($"Info:{mes}");
        }
    }

public static class ConsoleLogProviderExtensions
{
    public static void AddLog(this IServiceCollection services)
    {
        services.AddScoped<ILogProvider, ConsoleLogProvider>();
    }
}

3、邮件服务项目

/// <summary>
/// 邮件发送接口
/// </summary>
public interface IMailSender
{
    void Send(string title,string to,string msg);
}

 class DefaultMailSender : IMailSender
{ 
    private readonly ILogProvider log;
    private readonly IConfigProvider config;

    public DefaultMailSender(ILogProvider log, IConfigProvider config)//通过构造注入日志系统和配置系统
    {
        this.log = log;
        this.config = config;
    }
   //只是为了演示依赖注入,不是实际的邮件发送
    public void Send(string title, string to, string msg)
    {
        log.LogInfo("准备发送邮件");
        string smpt = config.GetValue("Smpt");
        string user = config.GetValue("User");
        string password = config.GetValue("Password");
        Console.WriteLine($"邮件服务器地址:{smpt},账号:{user},密码:{password}");
        Console.WriteLine($"向{title},{to}发送邮箱,{msg}");
    }

   
}

 public static class MailServiceExtensions
 {
     public static void AddMail(this IServiceCollection services)
     {
         services.AddScoped<IMailSender, DefaultMailSender>();
     }
 }

4、邮件发送应用程序

 因为配置服务目前只实现了一个简单的环境变量读取,所以在运行时需要先配置下环境变量,以下是我的环境变量配置

 

 internal class Program
 {
     static void Main(string[] args)
     {
         ServiceCollection services = new ServiceCollection();
         services.AddLog();
         services.AddEnvVarConfig();
         services.AddMail();

        using(ServiceProvider sp=services.BuildServiceProvider())
         {
            
             IMailSender mailSender = sp.GetRequiredService<IMailSender>();
             mailSender.Send("xxx@168.com", "Lily", "hello,Nice to meet you");
         }
     }
 }

 

运行结果: