说说KeyedService

在.NET8中,引入了KeyedService,用自定义关键字来使用服务,就是当注入多个接口子类的时候,可以通过命名关键字来区分,然后在使用时,使用关键字来调用。‍‍‍‍‍‍

下面看一个例子,通知服务接口INotifyService有两个子类,SMSService和EMailService。同时这些子类会调用不同的Respository。

public interface INotifyService
{
    bool Notify(string message);
}


public class SMSService : INotifyService
{
    private readonly Dictionary<string, dynamic> _configs;
    private readonly ILogger<EMailService> _logger;
    public SMSService([FromKeyedServices("smsRep")] IConfigRepository configRepository, ILogger<EMailService> logger)
    {
        _logger = logger;
        _configs = configRepository.GetConfig();
    }
    public bool Notify(string message)
    {
        _logger.LogInformation($"{_configs["name"]},SMSService,这里根据配置文件完成短信的通知发送,Message:{message}");
        return true;
    }
}
public class EMailService : INotifyService
{
    private readonly Dictionary<string, dynamic> _configs;
    private readonly ILogger<EMailService> _logger;
    public EMailService([FromKeyedServices("emailRep")] IConfigRepository configRepository, ILogger<EMailService> logger)
    {
        _logger = logger;
        _configs = configRepository.GetConfig();
    }
    public bool Notify(string message)
    {
        _logger.LogInformation($"{_configs["name"]},EMailService,这里根据配置文件完成邮件的通知发送,Message:{message}");
        return true;
    }
}
public interface IConfigRepository
{
    Dictionary<string, dynamic> GetConfig();
}
public class IEMailConfigRepository : IConfigRepository
{
    public Dictionary<string, dynamic> GetConfig()
    {
        //从数据库中获取配置信息
        return new Dictionary<string, dynamic>() { { "name", "email配置" } };
    }
}
public class ISMSConfigRepository : IConfigRepository
{
    public Dictionary<string, dynamic> GetConfig()
    {
        //从数据库中获取配置信息
        return new Dictionary<string, dynamic>() { { "name", "sms配置" } }; ;
    }
}

最后,再定义两个使用类SMS和EMail,在使上KeyedService时,需要用特性[FromKeyedServices("命名")],但这个特性不能直接使用在app.Map方法中,所以这里才有定义SMS和EMail两个类,再通过AddScoped的方式注放的写法。

using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.DependencyInjection;
using System.Collections;
using System.Collections.Generic;


var builder = WebApplication.CreateSlimBuilder(args);


builder.Services.AddScoped<SMS>();
builder.Services.AddScoped<EMail>();


builder.Services.AddKeyedScoped<IConfigRepository, ISMSConfigRepository>("smsRep");
builder.Services.AddKeyedScoped<IConfigRepository, IEMailConfigRepository>("emailRep");


builder.Services.AddKeyedScoped<INotifyService, EMailService>("emailSev");
builder.Services.AddKeyedScoped<INotifyService, SMSService>("smsSev");
var app = builder.Build();


app.MapGet("/sms", ([FromServices]SMS sms, string message) => new { Result = sms.Notify(message), Messgae = message, Type = sms.GetType().Name });
app.MapGet("/email", ([FromServices] EMail email, string message) => new { Result = email.Notify(message), Messgae = message, Type = email.GetType().Name });


//错误写法
//app.MapGet("/sms", ([FromKeyedServices("smsSev")] INotifyService notifyService, string message) => new { Result = notifyService.Notify(message), Messgae = message, Type = notifyService.GetType().Name });
//app.MapGet("/email", ([FromKeyedServices("smsSev")] INotifyService notifyService, string message) => new { Result = notifyService.Notify(message), Messgae = message, Type = notifyService.GetType().Name });


app.Run();


public class SMS([FromKeyedServices("smsSev")] INotifyService notifyService)
{
    public bool Notify(string message)
    {
        return notifyService.Notify(message);
    }
}
public class EMail([FromKeyedServices("emailSev")] INotifyService notifyService)
{
    public bool Notify(string message)
    {
        return notifyService.Notify(message);
    }
}

还有一种写法如下,可以做到简化,就是通过AddSingleton方式注入,然后用app.Services.GetRequiredKeyedService方式来获取通知接口,进行使用。

builder.Services.AddKeyedSingleton<IConfigRepository, IEMailConfigRepository>("emailRep");
builder.Services.AddKeyedSingleton<INotifyService, EMailService>("emailSev");
var app = builder.Build();
app.MapGet("/email", (string message) =>
{
    var email = app.Services.GetRequiredKeyedService<INotifyService>("emailSev");
    return new { Result = email.Notify(message), Messgae = message, Type = email.GetType().Name };
});

说说我使用的感受,感觉KeyedService使用有很多限制,不是很顺畅,也可能是Preview阶段,希望正式版本有所改善。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值