依赖注入 #
概述 #
Semantic Kernel 支持与 .NET 依赖注入(DI)系统深度集成,方便在 ASP.NET Core 等应用中使用。
基本配置 #
服务注册 #
csharp
using Microsoft.Extensions.DependencyInjection;
using Microsoft.SemanticKernel;
var services = new ServiceCollection();
services.AddKernel()
.AddOpenAIChatCompletion(
modelId: "gpt-4",
apiKey: Environment.GetEnvironmentVariable("OPENAI_API_KEY")
);
var serviceProvider = services.BuildServiceProvider();
var kernel = serviceProvider.GetRequiredService<Kernel>();
多服务配置 #
csharp
services.AddKernel()
.AddOpenAIChatCompletion(
serviceId: "openai-gpt4",
modelId: "gpt-4",
apiKey: "openai-key"
)
.AddAzureOpenAIChatCompletion(
serviceId: "azure-gpt4",
deploymentName: "gpt-4-deployment",
endpoint: "https://your-resource.openai.azure.com/",
apiKey: "azure-key"
)
.AddOpenAITextEmbeddingGeneration(
modelId: "text-embedding-3-small",
apiKey: "api-key"
);
ASP.NET Core 集成 #
Program.cs 配置 #
csharp
using Microsoft.SemanticKernel;
var builder = WebApplication.CreateBuilder(args);
// 添加 Semantic Kernel
builder.Services.AddKernel()
.AddAzureOpenAIChatCompletion(
deploymentName: builder.Configuration["AzureOpenAI:DeploymentName"]!,
endpoint: builder.Configuration["AzureOpenAI:Endpoint"]!,
apiKey: builder.Configuration["AzureOpenAI:ApiKey"]!
);
// 添加插件
builder.Services.AddTransient<WeatherPlugin>();
builder.Services.AddTransient<EmailPlugin>();
// 添加服务
builder.Services.AddScoped<IChatService, ChatService>();
builder.Services.AddScoped<IDocumentService, DocumentService>();
var app = builder.Build();
控制器中使用 #
csharp
[ApiController]
[Route("api/[controller]")]
public class ChatController : ControllerBase
{
private readonly Kernel _kernel;
private readonly IChatService _chatService;
public ChatController(Kernel kernel, IChatService chatService)
{
_kernel = kernel;
_chatService = chatService;
}
[HttpPost]
public async Task<IActionResult> Chat([FromBody] ChatRequest request)
{
var result = await _kernel.InvokePromptAsync(request.Message);
return Ok(new { response = result.ToString() });
}
}
插件注册 #
方式一:自动注册 #
csharp
// 注册插件类
builder.Services.AddTransient<WeatherPlugin>();
builder.Services.AddTransient<EmailPlugin>();
builder.Services.AddTransient<DatabasePlugin>();
// Kernel 会自动解析依赖
方式二:工厂注册 #
csharp
builder.Services.AddTransient<Kernel>(sp =>
{
var kernel = Kernel.Builder()
.AddOpenAIChatCompletion("gpt-4", "api-key")
.Build();
// 手动添加插件
kernel.Plugins.AddFromType<WeatherPlugin>();
kernel.Plugins.AddFromType<EmailPlugin>();
return kernel;
});
方式三:配置式注册 #
csharp
public class KernelConfigurator
{
public static void Configure(IServiceCollection services, IConfiguration configuration)
{
services.AddKernel()
.AddAzureOpenAIChatCompletion(
deploymentName: configuration["AzureOpenAI:DeploymentName"]!,
endpoint: configuration["AzureOpenAI:Endpoint"]!,
apiKey: configuration["AzureOpenAI:ApiKey"]!
);
// 根据配置注册插件
var enabledPlugins = configuration.GetSection("Plugins").Get<string[]>();
foreach (var plugin in enabledPlugins ?? Array.Empty<string>())
{
switch (plugin)
{
case "Weather":
services.AddTransient<WeatherPlugin>();
break;
case "Email":
services.AddTransient<EmailPlugin>();
break;
}
}
}
}
服务注入 #
在插件中注入服务 #
csharp
public class DatabasePlugin
{
private readonly IDatabaseService _db;
private readonly ILogger<DatabasePlugin> _logger;
public DatabasePlugin(
IDatabaseService db,
ILogger<DatabasePlugin> logger)
{
_db = db;
_logger = logger;
}
[KernelFunction("query")]
public async Task<string> QueryAsync(string sql)
{
_logger.LogInformation("执行查询: {SQL}", sql);
return await _db.ExecuteQueryAsync(sql);
}
}
在服务中使用 Kernel #
csharp
public class ChatService : IChatService
{
private readonly Kernel _kernel;
private readonly IChatHistoryRepository _historyRepo;
private readonly ILogger<ChatService> _logger;
public ChatService(
Kernel kernel,
IChatHistoryRepository historyRepo,
ILogger<ChatService> logger)
{
_kernel = kernel;
_historyRepo = historyRepo;
_logger = logger;
}
public async Task<string> ChatAsync(string userId, string message)
{
// 获取历史
var history = await _historyRepo.GetHistoryAsync(userId);
// 构建上下文
var chatHistory = new ChatHistory();
chatHistory.AddSystemMessage("你是一个友好的助手。");
foreach (var msg in history)
{
chatHistory.AddUserMessage(msg.UserMessage);
chatHistory.AddAssistantMessage(msg.AssistantMessage);
}
chatHistory.AddUserMessage(message);
// 获取回复
var chatService = _kernel.GetRequiredService<IChatCompletionService>();
var response = await chatService.GetChatMessageContentAsync(chatHistory);
// 保存历史
await _historyRepo.SaveHistoryAsync(userId, message, response.Content!);
return response.Content!;
}
}
配置管理 #
appsettings.json #
json
{
"SemanticKernel": {
"Provider": "AzureOpenAI",
"AzureOpenAI": {
"Endpoint": "https://your-resource.openai.azure.com/",
"DeploymentName": "gpt-4-deployment",
"ApiKey": ""
},
"OpenAI": {
"ModelId": "gpt-4",
"ApiKey": "",
"OrgId": ""
},
"Embedding": {
"ModelId": "text-embedding-3-small"
}
},
"Plugins": ["Weather", "Email", "Database"]
}
配置类 #
csharp
public class SemanticKernelOptions
{
public string Provider { get; set; } = "OpenAI";
public AzureOpenAIOptions AzureOpenAI { get; set; } = new();
public OpenAIOptions OpenAI { get; set; } = new();
public EmbeddingOptions Embedding { get; set; } = new();
}
public class AzureOpenAIOptions
{
public string Endpoint { get; set; } = "";
public string DeploymentName { get; set; } = "";
public string ApiKey { get; set; } = "";
}
public class OpenAIOptions
{
public string ModelId { get; set; } = "gpt-4";
public string ApiKey { get; set; } = "";
public string? OrgId { get; set; }
}
public class EmbeddingOptions
{
public string ModelId { get; set; } = "text-embedding-3-small";
}
配置绑定 #
csharp
builder.Services.Configure<SemanticKernelOptions>(
builder.Configuration.GetSection("SemanticKernel"));
// 使用配置
builder.Services.AddKernelServices(builder.Configuration);
public static class ServiceCollectionExtensions
{
public static IServiceCollection AddKernelServices(
this IServiceCollection services,
IConfiguration configuration)
{
var options = configuration.GetSection("SemanticKernel")
.Get<SemanticKernelOptions>();
var kernelBuilder = services.AddKernel();
switch (options.Provider)
{
case "AzureOpenAI":
kernelBuilder.AddAzureOpenAIChatCompletion(
options.AzureOpenAI.DeploymentName,
options.AzureOpenAI.Endpoint,
options.AzureOpenAI.ApiKey
);
break;
case "OpenAI":
kernelBuilder.AddOpenAIChatCompletion(
options.OpenAI.ModelId,
options.OpenAI.ApiKey,
options.OpenAI.OrgId
);
break;
}
kernelBuilder.AddOpenAITextEmbeddingGeneration(
options.Embedding.ModelId,
options.OpenAI.ApiKey
);
return services;
}
}
作用域管理 #
Scoped Kernel #
csharp
// 每个 Scope 创建新的 Kernel 实例
builder.Services.AddScoped<Kernel>(sp =>
{
var configuration = sp.GetRequiredService<IConfiguration>();
return Kernel.CreateBuilder()
.AddOpenAIChatCompletion(
configuration["OpenAI:ModelId"]!,
configuration["OpenAI:ApiKey"]!
)
.Build();
});
Singleton Kernel #
csharp
// 全局共享 Kernel 实例
builder.Services.AddSingleton<Kernel>(sp =>
{
var configuration = sp.GetRequiredService<IConfiguration>();
return Kernel.CreateBuilder()
.AddOpenAIChatCompletion(
configuration["OpenAI:ModelId"]!,
configuration["OpenAI:ApiKey"]!
)
.Build();
});
测试支持 #
模拟 Kernel #
csharp
public class MockKernelBuilder
{
public static Kernel BuildMockKernel()
{
var mockChatService = new Mock<IChatCompletionService>();
mockChatService
.Setup(s => s.GetChatMessageContentsAsync(
It.IsAny<ChatHistory>(),
It.IsAny<PromptExecutionSettings>(),
It.IsAny<Kernel>(),
It.IsAny<CancellationToken>()))
.ReturnsAsync(new List<ChatMessageContent>
{
new(AuthorRole.Assistant, "模拟响应")
});
var kernel = new Kernel();
kernel.AddService(mockChatService.Object);
return kernel;
}
}
测试示例 #
csharp
public class ChatServiceTests
{
private readonly Kernel _mockKernel;
private readonly Mock<IChatHistoryRepository> _mockRepo;
private readonly ChatService _service;
public ChatServiceTests()
{
_mockKernel = MockKernelBuilder.BuildMockKernel();
_mockRepo = new Mock<IChatHistoryRepository>();
_service = new ChatService(_mockKernel, _mockRepo.Object);
}
[Fact]
public async Task ChatAsync_ReturnsResponse()
{
var result = await _service.ChatAsync("user1", "你好");
Assert.NotNull(result);
}
}
最佳实践 #
1. 使用配置文件 #
csharp
// 推荐:使用配置
builder.Services.AddKernel()
.AddOpenAIChatCompletion(
configuration["OpenAI:ModelId"]!,
configuration["OpenAI:ApiKey"]!
);
// 避免:硬编码
builder.Services.AddKernel()
.AddOpenAIChatCompletion("gpt-4", "hardcoded-key");
2. 安全存储密钥 #
csharp
// 使用 Azure Key Vault
builder.Services.AddAzureClients(builder =>
{
builder.AddSecretClient(builder.Configuration.GetSection("KeyVault"));
});
// 或使用环境变量
var apiKey = Environment.GetEnvironmentVariable("OPENAI_API_KEY");
3. 合理的生命周期 #
csharp
// Kernel: Singleton(共享连接池)
builder.Services.AddSingleton<Kernel>();
// 服务: Scoped(每个请求)
builder.Services.AddScoped<IChatService, ChatService>();
// 插件: Transient(每次创建)
builder.Services.AddTransient<WeatherPlugin>();
下一步 #
现在你已经掌握了依赖注入,接下来学习 智能聊天机器人,开始实战项目!
最后更新:2026-04-04