.Net: Add a Unit Test to ensure the Service Attributes defined previously in the service are available in the ServiceSelector to be used as a filter. (#4854)

### Motivation and Context

Closes #3465 

### Description

<!-- Describe your changes, the overall approach, the underlying design.
These notes will help understanding how your code works. Thanks! -->

### Contribution Checklist

<!-- Before submitting this PR, please make sure: -->

- [ ] The code builds clean without any errors or warnings
- [ ] The PR follows the [SK Contribution
Guidelines](https://github.com/microsoft/semantic-kernel/blob/main/CONTRIBUTING.md)
and the [pre-submission formatting
script](https://github.com/microsoft/semantic-kernel/blob/main/CONTRIBUTING.md#development-scripts)
raises no violations
- [ ] All unit tests pass, and I have added new tests where possible
- [ ] I didn't break anyone 😄
This commit is contained in:
Mark Wallace
2024-02-02 18:15:17 +00:00
committed by GitHub
parent 9ae69a43fc
commit eed51932f2
@@ -0,0 +1,64 @@
// Copyright (c) Microsoft. All rights reserved.
using System.Collections.Generic;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Services;
using Xunit;
namespace SemanticKernel.UnitTests.Functions;
public class CustomAIServiceSelectorTests
{
[Fact]
public void ItGetsAIServiceUsingArbitraryAttributes()
{
// Arrange
IKernelBuilder builder = Kernel.CreateBuilder();
builder.Services.AddKeyedSingleton<IAIService>("service1", new AIService());
Kernel kernel = builder.Build();
var function = kernel.CreateFunctionFromPrompt("Hello AI");
var serviceSelector = new CustomAIServiceSelector();
// Act
(var aiService, var defaultExecutionSettings) = serviceSelector.SelectAIService<IAIService>(kernel, function, new KernelArguments());
// Assert
Assert.NotNull(aiService);
Assert.True(aiService.Attributes?.ContainsKey("Key1"));
Assert.Null(defaultExecutionSettings);
}
private sealed class CustomAIServiceSelector : IAIServiceSelector
{
#pragma warning disable CS8769 // Nullability of reference types in value doesn't match target type. Cannot use [NotNullWhen] because of access to internals from abstractions.
bool IAIServiceSelector.TrySelectAIService<T>(Kernel kernel, KernelFunction function, KernelArguments arguments, out T? service, out PromptExecutionSettings? serviceSettings) where T : class
{
var keyedService = (kernel.Services as IKeyedServiceProvider)?.GetKeyedService<T>("service1");
if (keyedService is null || keyedService.Attributes is null)
{
service = null;
serviceSettings = null;
return false;
}
service = keyedService.Attributes.ContainsKey("Key1") ? keyedService as T : null;
serviceSettings = null;
return true;
}
}
private sealed class AIService : IAIService
{
public IReadOnlyDictionary<string, object?> Attributes => this._attributes;
public AIService()
{
this._attributes = new Dictionary<string, object?>();
this._attributes.Add("Key1", "Value1");
}
private readonly Dictionary<string, object?> _attributes;
}
}