Update M.E.AI.Abstractions to 9.5.0-preview.1.25262.9 (#412)

This commit is contained in:
Stephen Toub 2025-05-14 06:24:24 -04:00 • committed by GitHub
commit ca3a8ab921
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 68 additions and 58 deletions

View file

@ -2,7 +2,7 @@
<PropertyGroup> <PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally> <ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
<System10Version>10.0.0-preview.3.25171.5</System10Version> <System10Version>10.0.0-preview.3.25171.5</System10Version>
<MicrosoftExtensionsAIVersion>9.4.4-preview.1.25259.16</MicrosoftExtensionsAIVersion> <MicrosoftExtensionsAIVersion>9.5.0-preview.1.25262.9</MicrosoftExtensionsAIVersion>
</PropertyGroup> </PropertyGroup>
<!-- Product dependencies netstandard --> <!-- Product dependencies netstandard -->
@ -31,7 +31,7 @@
<!-- Product dependencies shared --> <!-- Product dependencies shared -->
<ItemGroup> <ItemGroup>
<PackageVersion Include="Microsoft.Extensions.AI.Abstractions" Version="9.4.4-preview.1.25259.16" /> <PackageVersion Include="Microsoft.Extensions.AI.Abstractions" Version="$(MicrosoftExtensionsAIVersion)" />
<PackageVersion Include="Microsoft.Extensions.AI" Version="$(MicrosoftExtensionsAIVersion)" /> <PackageVersion Include="Microsoft.Extensions.AI" Version="$(MicrosoftExtensionsAIVersion)" />
<PackageVersion Include="System.Net.ServerSentEvents" Version="$(System10Version)" /> <PackageVersion Include="System.Net.ServerSentEvents" Version="$(System10Version)" />
</ItemGroup> </ItemGroup>

View file

@ -48,7 +48,7 @@ public static partial class McpServerBuilderExtensions
{ {
builder.Services.AddSingleton((Func<IServiceProvider, McpServerTool>)(toolMethod.IsStatic ? builder.Services.AddSingleton((Func<IServiceProvider, McpServerTool>)(toolMethod.IsStatic ?
services => McpServerTool.Create(toolMethod, options: new() { Services = services, SerializerOptions = serializerOptions }) : services => McpServerTool.Create(toolMethod, options: new() { Services = services, SerializerOptions = serializerOptions }) :
services => McpServerTool.Create(toolMethod, typeof(TToolType), new() { Services = services, SerializerOptions = serializerOptions }))); services => McpServerTool.Create(toolMethod, static r => CreateTarget(r.Services, typeof(TToolType)), new() { Services = services, SerializerOptions = serializerOptions })));
} }
} }
@ -105,7 +105,7 @@ public static partial class McpServerBuilderExtensions
{ {
builder.Services.AddSingleton((Func<IServiceProvider, McpServerTool>)(toolMethod.IsStatic ? builder.Services.AddSingleton((Func<IServiceProvider, McpServerTool>)(toolMethod.IsStatic ?
services => McpServerTool.Create(toolMethod, options: new() { Services = services , SerializerOptions = serializerOptions }) : services => McpServerTool.Create(toolMethod, options: new() { Services = services , SerializerOptions = serializerOptions }) :
services => McpServerTool.Create(toolMethod, toolType, new() { Services = services , SerializerOptions = serializerOptions }))); services => McpServerTool.Create(toolMethod, r => CreateTarget(r.Services, toolType), new() { Services = services , SerializerOptions = serializerOptions })));
} }
} }
} }
@ -188,7 +188,7 @@ public static partial class McpServerBuilderExtensions
{ {
builder.Services.AddSingleton((Func<IServiceProvider, McpServerPrompt>)(promptMethod.IsStatic ? builder.Services.AddSingleton((Func<IServiceProvider, McpServerPrompt>)(promptMethod.IsStatic ?
services => McpServerPrompt.Create(promptMethod, options: new() { Services = services, SerializerOptions = serializerOptions }) : services => McpServerPrompt.Create(promptMethod, options: new() { Services = services, SerializerOptions = serializerOptions }) :
services => McpServerPrompt.Create(promptMethod, typeof(TPromptType), new() { Services = services, SerializerOptions = serializerOptions }))); services => McpServerPrompt.Create(promptMethod, static r => CreateTarget(r.Services, typeof(TPromptType)), new() { Services = services, SerializerOptions = serializerOptions })));
} }
} }
@ -245,7 +245,7 @@ public static partial class McpServerBuilderExtensions
{ {
builder.Services.AddSingleton((Func<IServiceProvider, McpServerPrompt>)(promptMethod.IsStatic ? builder.Services.AddSingleton((Func<IServiceProvider, McpServerPrompt>)(promptMethod.IsStatic ?
services => McpServerPrompt.Create(promptMethod, options: new() { Services = services, SerializerOptions = serializerOptions }) : services => McpServerPrompt.Create(promptMethod, options: new() { Services = services, SerializerOptions = serializerOptions }) :
services => McpServerPrompt.Create(promptMethod, promptType, new() { Services = services, SerializerOptions = serializerOptions }))); services => McpServerPrompt.Create(promptMethod, r => CreateTarget(r.Services, promptType), new() { Services = services, SerializerOptions = serializerOptions })));
} }
} }
} }
@ -325,7 +325,7 @@ public static partial class McpServerBuilderExtensions
{ {
builder.Services.AddSingleton((Func<IServiceProvider, McpServerResource>)(resourceTemplateMethod.IsStatic ? builder.Services.AddSingleton((Func<IServiceProvider, McpServerResource>)(resourceTemplateMethod.IsStatic ?
services => McpServerResource.Create(resourceTemplateMethod, options: new() { Services = services }) : services => McpServerResource.Create(resourceTemplateMethod, options: new() { Services = services }) :
services => McpServerResource.Create(resourceTemplateMethod, typeof(TResourceType), new() { Services = services }))); services => McpServerResource.Create(resourceTemplateMethod, static r => CreateTarget(r.Services, typeof(TResourceType)), new() { Services = services })));
} }
} }
@ -381,7 +381,7 @@ public static partial class McpServerBuilderExtensions
{ {
builder.Services.AddSingleton((Func<IServiceProvider, McpServerResource>)(resourceTemplateMethod.IsStatic ? builder.Services.AddSingleton((Func<IServiceProvider, McpServerResource>)(resourceTemplateMethod.IsStatic ?
services => McpServerResource.Create(resourceTemplateMethod, options: new() { Services = services }) : services => McpServerResource.Create(resourceTemplateMethod, options: new() { Services = services }) :
services => McpServerResource.Create(resourceTemplateMethod, resourceTemplateType, new() { Services = services }))); services => McpServerResource.Create(resourceTemplateMethod, r => CreateTarget(r.Services, resourceTemplateType), new() { Services = services })));
} }
} }
} }
@ -775,4 +775,13 @@ public static partial class McpServerBuilderExtensions
}); });
} }
#endregion #endregion
#region Helpers
/// <summary>Creates an instance of the target object.</summary>
private static object CreateTarget(
IServiceProvider? services,
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type type) =>
services is not null ? ActivatorUtilities.CreateInstance(services, type) :
Activator.CreateInstance(type)!;
#endregion
} }

View file

@ -4,7 +4,6 @@ using ModelContextProtocol.Protocol.Types;
using ModelContextProtocol.Utils; using ModelContextProtocol.Utils;
using ModelContextProtocol.Utils.Json; using ModelContextProtocol.Utils.Json;
using System.ComponentModel; using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Reflection; using System.Reflection;
using System.Text.Json; using System.Text.Json;
@ -49,15 +48,20 @@ internal sealed class AIFunctionMcpServerPrompt : McpServerPrompt
/// </summary> /// </summary>
public static new AIFunctionMcpServerPrompt Create( public static new AIFunctionMcpServerPrompt Create(
MethodInfo method, MethodInfo method,
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type targetType, Func<RequestContext<GetPromptRequestParams>, object> createTargetFunc,
McpServerPromptCreateOptions? options) McpServerPromptCreateOptions? options)
{ {
Throw.IfNull(method); Throw.IfNull(method);
Throw.IfNull(createTargetFunc);
options = DeriveOptions(method, options); options = DeriveOptions(method, options);
return Create( return Create(
AIFunctionFactory.Create(method, targetType, CreateAIFunctionFactoryOptions(method, options)), AIFunctionFactory.Create(method, args =>
{
var request = (RequestContext<GetPromptRequestParams>)args.Context![typeof(RequestContext<GetPromptRequestParams>)]!;
return createTargetFunc(request);
}, CreateAIFunctionFactoryOptions(method, options)),
options); options);
} }
@ -69,7 +73,6 @@ internal sealed class AIFunctionMcpServerPrompt : McpServerPrompt
Description = options?.Description, Description = options?.Description,
MarshalResult = static (result, _, cancellationToken) => new ValueTask<object?>(result), MarshalResult = static (result, _, cancellationToken) => new ValueTask<object?>(result),
SerializerOptions = options?.SerializerOptions ?? McpJsonUtilities.DefaultOptions, SerializerOptions = options?.SerializerOptions ?? McpJsonUtilities.DefaultOptions,
CreateInstance = AIFunctionMcpServerTool.GetCreateInstanceFunc(),
ConfigureParameterBinding = pi => ConfigureParameterBinding = pi =>
{ {
if (pi.ParameterType == typeof(RequestContext<GetPromptRequestParams>)) if (pi.ParameterType == typeof(RequestContext<GetPromptRequestParams>))

View file

@ -5,7 +5,6 @@ using ModelContextProtocol.Utils;
using ModelContextProtocol.Utils.Json; using ModelContextProtocol.Utils.Json;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.ComponentModel; using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Globalization; using System.Globalization;
using System.Reflection; using System.Reflection;
using System.Text; using System.Text;
@ -56,15 +55,20 @@ internal sealed class AIFunctionMcpServerResource : McpServerResource
/// </summary> /// </summary>
public static new AIFunctionMcpServerResource Create( public static new AIFunctionMcpServerResource Create(
MethodInfo method, MethodInfo method,
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type targetType, Func<RequestContext<ReadResourceRequestParams>, object> createTargetFunc,
McpServerResourceCreateOptions? options) McpServerResourceCreateOptions? options)
{ {
Throw.IfNull(method); Throw.IfNull(method);
Throw.IfNull(createTargetFunc);
options = DeriveOptions(method, options); options = DeriveOptions(method, options);
return Create( return Create(
AIFunctionFactory.Create(method, targetType, CreateAIFunctionFactoryOptions(method, options)), AIFunctionFactory.Create(method, args =>
{
var request = (RequestContext<ReadResourceRequestParams>)args.Context![typeof(RequestContext<ReadResourceRequestParams>)]!;
return createTargetFunc(request);
}, CreateAIFunctionFactoryOptions(method, options)),
options); options);
} }
@ -76,7 +80,6 @@ internal sealed class AIFunctionMcpServerResource : McpServerResource
Description = options?.Description, Description = options?.Description,
MarshalResult = static (result, _, cancellationToken) => new ValueTask<object?>(result), MarshalResult = static (result, _, cancellationToken) => new ValueTask<object?>(result),
SerializerOptions = McpJsonUtilities.DefaultOptions, SerializerOptions = McpJsonUtilities.DefaultOptions,
CreateInstance = AIFunctionMcpServerTool.GetCreateInstanceFunc(),
ConfigureParameterBinding = pi => ConfigureParameterBinding = pi =>
{ {
if (pi.ParameterType == typeof(RequestContext<ReadResourceRequestParams>)) if (pi.ParameterType == typeof(RequestContext<ReadResourceRequestParams>))

View file

@ -49,15 +49,20 @@ internal sealed class AIFunctionMcpServerTool : McpServerTool
/// </summary> /// </summary>
public static new AIFunctionMcpServerTool Create( public static new AIFunctionMcpServerTool Create(
MethodInfo method, MethodInfo method,
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type targetType, Func<RequestContext<CallToolRequestParams>, object> createTargetFunc,
McpServerToolCreateOptions? options) McpServerToolCreateOptions? options)
{ {
Throw.IfNull(method); Throw.IfNull(method);
Throw.IfNull(createTargetFunc);
options = DeriveOptions(method, options); options = DeriveOptions(method, options);
return Create( return Create(
AIFunctionFactory.Create(method, targetType, CreateAIFunctionFactoryOptions(method, options)), AIFunctionFactory.Create(method, args =>
{
var request = (RequestContext<CallToolRequestParams>)args.Context![typeof(RequestContext<CallToolRequestParams>)]!;
return createTargetFunc(request);
}, CreateAIFunctionFactoryOptions(method, options)),
options); options);
} }
@ -77,7 +82,6 @@ internal sealed class AIFunctionMcpServerTool : McpServerTool
Description = options?.Description, Description = options?.Description,
MarshalResult = static (result, _, cancellationToken) => new ValueTask<object?>(result), MarshalResult = static (result, _, cancellationToken) => new ValueTask<object?>(result),
SerializerOptions = options?.SerializerOptions ?? McpJsonUtilities.DefaultOptions, SerializerOptions = options?.SerializerOptions ?? McpJsonUtilities.DefaultOptions,
CreateInstance = GetCreateInstanceFunc(),
ConfigureParameterBinding = pi => ConfigureParameterBinding = pi =>
{ {
if (pi.ParameterType == typeof(RequestContext<CallToolRequestParams>)) if (pi.ParameterType == typeof(RequestContext<CallToolRequestParams>))

View file

@ -3,7 +3,6 @@ using Microsoft.Extensions.DependencyInjection;
using ModelContextProtocol.Client; using ModelContextProtocol.Client;
using ModelContextProtocol.Protocol.Messages; using ModelContextProtocol.Protocol.Messages;
using ModelContextProtocol.Protocol.Types; using ModelContextProtocol.Protocol.Types;
using System.Diagnostics.CodeAnalysis;
using System.Reflection; using System.Reflection;
using System.Text.Json; using System.Text.Json;
@ -184,21 +183,19 @@ public abstract class McpServerPrompt : IMcpServerPrimitive
/// instantiate each time the method is invoked. /// instantiate each time the method is invoked.
/// </summary> /// </summary>
/// <param name="method">The instance method to be represented via the created <see cref="AIFunction"/>.</param> /// <param name="method">The instance method to be represented via the created <see cref="AIFunction"/>.</param>
/// <param name="targetType"> /// <param name="createTargetFunc">
/// The <see cref="Type"/> to construct an instance of on which to invoke <paramref name="method"/> when /// Callback used on each function invocation to create an instance of the type on which the instance method <paramref name="method"/>
/// the resulting <see cref="AIFunction"/> is invoked. If services are provided, /// will be invoked. If the returned instance is <see cref="IAsyncDisposable"/> or <see cref="IDisposable"/>, it will
/// ActivatorUtilities.CreateInstance will be used to construct the instance using those services; otherwise, /// be disposed of after method completes its invocation.
/// <see cref="Activator.CreateInstance(Type)"/> is used, utilizing the type's public parameterless constructor.
/// If an instance can't be constructed, an exception is thrown during the function's invocation.
/// </param> /// </param>
/// <param name="options">Optional options used in the creation of the <see cref="McpServerPrompt"/> to control its behavior.</param> /// <param name="options">Optional options used in the creation of the <see cref="McpServerPrompt"/> to control its behavior.</param>
/// <returns>The created <see cref="AIFunction"/> for invoking <paramref name="method"/>.</returns> /// <returns>The created <see cref="AIFunction"/> for invoking <paramref name="method"/>.</returns>
/// <exception cref="ArgumentNullException"><paramref name="method"/> is <see langword="null"/>.</exception> /// <exception cref="ArgumentNullException"><paramref name="method"/> is <see langword="null"/>.</exception>
public static McpServerPrompt Create( public static McpServerPrompt Create(
MethodInfo method, MethodInfo method,
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type targetType, Func<RequestContext<GetPromptRequestParams>, object> createTargetFunc,
McpServerPromptCreateOptions? options = null) => McpServerPromptCreateOptions? options = null) =>
AIFunctionMcpServerPrompt.Create(method, targetType, options); AIFunctionMcpServerPrompt.Create(method, createTargetFunc, options);
/// <summary>Creates an <see cref="McpServerPrompt"/> that wraps the specified <see cref="AIFunction"/>.</summary> /// <summary>Creates an <see cref="McpServerPrompt"/> that wraps the specified <see cref="AIFunction"/>.</summary>
/// <param name="function">The function to wrap.</param> /// <param name="function">The function to wrap.</param>

View file

@ -2,7 +2,6 @@ using Microsoft.Extensions.AI;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using ModelContextProtocol.Protocol.Messages; using ModelContextProtocol.Protocol.Messages;
using ModelContextProtocol.Protocol.Types; using ModelContextProtocol.Protocol.Types;
using System.Diagnostics.CodeAnalysis;
using System.Reflection; using System.Reflection;
namespace ModelContextProtocol.Server; namespace ModelContextProtocol.Server;
@ -205,21 +204,19 @@ public abstract class McpServerResource : IMcpServerPrimitive
/// instantiate each time the method is invoked. /// instantiate each time the method is invoked.
/// </summary> /// </summary>
/// <param name="method">The instance method to be represented via the created <see cref="AIFunction"/>.</param> /// <param name="method">The instance method to be represented via the created <see cref="AIFunction"/>.</param>
/// <param name="targetType"> /// <param name="createTargetFunc">
/// The <see cref="Type"/> to construct an instance of on which to invoke <paramref name="method"/> when /// Callback used on each function invocation to create an instance of the type on which the instance method <paramref name="method"/>
/// the resulting <see cref="AIFunction"/> is invoked. If services are provided, /// will be invoked. If the returned instance is <see cref="IAsyncDisposable"/> or <see cref="IDisposable"/>, it will
/// ActivatorUtilities.CreateInstance will be used to construct the instance using those services; otherwise, /// be disposed of after method completes its invocation.
/// <see cref="Activator.CreateInstance(Type)"/> is used, utilizing the type's public parameterless constructor.
/// If an instance can't be constructed, an exception is thrown during the function's invocation.
/// </param> /// </param>
/// <param name="options">Optional options used in the creation of the <see cref="McpServerResource"/> to control its behavior.</param> /// <param name="options">Optional options used in the creation of the <see cref="McpServerResource"/> to control its behavior.</param>
/// <returns>The created <see cref="AIFunction"/> for invoking <paramref name="method"/>.</returns> /// <returns>The created <see cref="AIFunction"/> for invoking <paramref name="method"/>.</returns>
/// <exception cref="ArgumentNullException"><paramref name="method"/> is <see langword="null"/>.</exception> /// <exception cref="ArgumentNullException"><paramref name="method"/> is <see langword="null"/>.</exception>
public static McpServerResource Create( public static McpServerResource Create(
MethodInfo method, MethodInfo method,
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type targetType, Func<RequestContext<ReadResourceRequestParams>, object> createTargetFunc,
McpServerResourceCreateOptions? options = null) => McpServerResourceCreateOptions? options = null) =>
AIFunctionMcpServerResource.Create(method, targetType, options); AIFunctionMcpServerResource.Create(method, createTargetFunc, options);
/// <summary>Creates an <see cref="McpServerResource"/> that wraps the specified <see cref="AIFunction"/>.</summary> /// <summary>Creates an <see cref="McpServerResource"/> that wraps the specified <see cref="AIFunction"/>.</summary>
/// <param name="function">The function to wrap.</param> /// <param name="function">The function to wrap.</param>

View file

@ -4,7 +4,6 @@ using ModelContextProtocol.Client;
using ModelContextProtocol.Protocol.Messages; using ModelContextProtocol.Protocol.Messages;
using ModelContextProtocol.Protocol.Types; using ModelContextProtocol.Protocol.Types;
using ModelContextProtocol.Utils.Json; using ModelContextProtocol.Utils.Json;
using System.Diagnostics.CodeAnalysis;
using System.Reflection; using System.Reflection;
using System.Text.Json; using System.Text.Json;
@ -187,21 +186,19 @@ public abstract class McpServerTool : IMcpServerPrimitive
/// instantiate each time the method is invoked. /// instantiate each time the method is invoked.
/// </summary> /// </summary>
/// <param name="method">The instance method to be represented via the created <see cref="AIFunction"/>.</param> /// <param name="method">The instance method to be represented via the created <see cref="AIFunction"/>.</param>
/// <param name="targetType"> /// <param name="createTargetFunc">
/// The <see cref="Type"/> to construct an instance of on which to invoke <paramref name="method"/> when /// Callback used on each function invocation to create an instance of the type on which the instance method <paramref name="method"/>
/// the resulting <see cref="AIFunction"/> is invoked. If services are provided, /// will be invoked. If the returned instance is <see cref="IAsyncDisposable"/> or <see cref="IDisposable"/>, it will
/// ActivatorUtilities.CreateInstance will be used to construct the instance using those services; otherwise, /// be disposed of after method completes its invocation.
/// <see cref="Activator.CreateInstance(Type)"/> is used, utilizing the type's public parameterless constructor.
/// If an instance can't be constructed, an exception is thrown during the function's invocation.
/// </param> /// </param>
/// <param name="options">Optional options used in the creation of the <see cref="McpServerTool"/> to control its behavior.</param> /// <param name="options">Optional options used in the creation of the <see cref="McpServerTool"/> to control its behavior.</param>
/// <returns>The created <see cref="AIFunction"/> for invoking <paramref name="method"/>.</returns> /// <returns>The created <see cref="AIFunction"/> for invoking <paramref name="method"/>.</returns>
/// <exception cref="ArgumentNullException"><paramref name="method"/> is <see langword="null"/>.</exception> /// <exception cref="ArgumentNullException"><paramref name="method"/> is <see langword="null"/>.</exception>
public static McpServerTool Create( public static McpServerTool Create(
MethodInfo method, MethodInfo method,
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type targetType, Func<RequestContext<CallToolRequestParams>, object> createTargetFunc,
McpServerToolCreateOptions? options = null) => McpServerToolCreateOptions? options = null) =>
AIFunctionMcpServerTool.Create(method, targetType, options); AIFunctionMcpServerTool.Create(method, createTargetFunc, options);
/// <summary>Creates an <see cref="McpServerTool"/> that wraps the specified <see cref="AIFunction"/>.</summary> /// <summary>Creates an <see cref="McpServerTool"/> that wraps the specified <see cref="AIFunction"/>.</summary>
/// <param name="function">The function to wrap.</param> /// <param name="function">The function to wrap.</param>

View file

@ -15,8 +15,8 @@ public class McpServerPromptTests
{ {
Assert.Throws<ArgumentNullException>("function", () => McpServerPrompt.Create((AIFunction)null!)); Assert.Throws<ArgumentNullException>("function", () => McpServerPrompt.Create((AIFunction)null!));
Assert.Throws<ArgumentNullException>("method", () => McpServerPrompt.Create((MethodInfo)null!)); Assert.Throws<ArgumentNullException>("method", () => McpServerPrompt.Create((MethodInfo)null!));
Assert.Throws<ArgumentNullException>("method", () => McpServerPrompt.Create((MethodInfo)null!, typeof(object))); Assert.Throws<ArgumentNullException>("method", () => McpServerPrompt.Create((MethodInfo)null!, _ => new object()));
Assert.Throws<ArgumentNullException>("targetType", () => McpServerPrompt.Create(typeof(McpServerPromptTests).GetMethod(nameof(Create_InvalidArgs_Throws))!, (Type)null!)); Assert.Throws<ArgumentNullException>("createTargetFunc", () => McpServerPrompt.Create(typeof(McpServerPromptTests).GetMethod(nameof(Create_InvalidArgs_Throws))!, null!));
Assert.Throws<ArgumentNullException>("method", () => McpServerPrompt.Create((Delegate)null!)); Assert.Throws<ArgumentNullException>("method", () => McpServerPrompt.Create((Delegate)null!));
} }
@ -96,7 +96,7 @@ public class McpServerPromptTests
{ {
McpServerPrompt prompt1 = McpServerPrompt.Create( McpServerPrompt prompt1 = McpServerPrompt.Create(
typeof(DisposablePromptType).GetMethod(nameof(DisposablePromptType.InstanceMethod))!, typeof(DisposablePromptType).GetMethod(nameof(DisposablePromptType.InstanceMethod))!,
typeof(DisposablePromptType)); _ => new DisposablePromptType());
var result = await prompt1.GetAsync( var result = await prompt1.GetAsync(
new RequestContext<GetPromptRequestParams>(new Mock<IMcpServer>().Object), new RequestContext<GetPromptRequestParams>(new Mock<IMcpServer>().Object),
@ -109,7 +109,7 @@ public class McpServerPromptTests
{ {
McpServerPrompt prompt1 = McpServerPrompt.Create( McpServerPrompt prompt1 = McpServerPrompt.Create(
typeof(AsyncDisposablePromptType).GetMethod(nameof(AsyncDisposablePromptType.InstanceMethod))!, typeof(AsyncDisposablePromptType).GetMethod(nameof(AsyncDisposablePromptType.InstanceMethod))!,
typeof(AsyncDisposablePromptType)); _ => new AsyncDisposablePromptType());
var result = await prompt1.GetAsync( var result = await prompt1.GetAsync(
new RequestContext<GetPromptRequestParams>(new Mock<IMcpServer>().Object), new RequestContext<GetPromptRequestParams>(new Mock<IMcpServer>().Object),
@ -122,7 +122,7 @@ public class McpServerPromptTests
{ {
McpServerPrompt prompt1 = McpServerPrompt.Create( McpServerPrompt prompt1 = McpServerPrompt.Create(
typeof(AsyncDisposableAndDisposablePromptType).GetMethod(nameof(AsyncDisposableAndDisposablePromptType.InstanceMethod))!, typeof(AsyncDisposableAndDisposablePromptType).GetMethod(nameof(AsyncDisposableAndDisposablePromptType.InstanceMethod))!,
typeof(AsyncDisposableAndDisposablePromptType)); _ => new AsyncDisposableAndDisposablePromptType());
var result = await prompt1.GetAsync( var result = await prompt1.GetAsync(
new RequestContext<GetPromptRequestParams>(new Mock<IMcpServer>().Object), new RequestContext<GetPromptRequestParams>(new Mock<IMcpServer>().Object),

View file

@ -109,8 +109,8 @@ public partial class McpServerResourceTests
{ {
Assert.Throws<ArgumentNullException>("function", () => McpServerResource.Create((AIFunction)null!, new() { UriTemplate = "test://hello" })); Assert.Throws<ArgumentNullException>("function", () => McpServerResource.Create((AIFunction)null!, new() { UriTemplate = "test://hello" }));
Assert.Throws<ArgumentNullException>("method", () => McpServerResource.Create((MethodInfo)null!)); Assert.Throws<ArgumentNullException>("method", () => McpServerResource.Create((MethodInfo)null!));
Assert.Throws<ArgumentNullException>("method", () => McpServerResource.Create((MethodInfo)null!, typeof(object))); Assert.Throws<ArgumentNullException>("method", () => McpServerResource.Create((MethodInfo)null!, _ => new object()));
Assert.Throws<ArgumentNullException>("targetType", () => McpServerResource.Create(typeof(McpServerResourceTests).GetMethod(nameof(Create_InvalidArgs_Throws))!, (Type)null!)); Assert.Throws<ArgumentNullException>("createTargetFunc", () => McpServerResource.Create(typeof(McpServerResourceTests).GetMethod(nameof(Create_InvalidArgs_Throws))!, null!));
Assert.Throws<ArgumentNullException>("method", () => McpServerResource.Create((Delegate)null!)); Assert.Throws<ArgumentNullException>("method", () => McpServerResource.Create((Delegate)null!));
Assert.NotNull(McpServerResource.Create(typeof(DisposableResourceType).GetMethod(nameof(DisposableResourceType.InstanceMethod))!, new DisposableResourceType())); Assert.NotNull(McpServerResource.Create(typeof(DisposableResourceType).GetMethod(nameof(DisposableResourceType.InstanceMethod))!, new DisposableResourceType()));
@ -415,7 +415,7 @@ public partial class McpServerResourceTests
McpServerResource resource1 = McpServerResource.Create( McpServerResource resource1 = McpServerResource.Create(
typeof(DisposableResourceType).GetMethod(nameof(DisposableResourceType.InstanceMethod))!, typeof(DisposableResourceType).GetMethod(nameof(DisposableResourceType.InstanceMethod))!,
typeof(DisposableResourceType)); _ => new DisposableResourceType());
var result = await resource1.ReadAsync( var result = await resource1.ReadAsync(
new RequestContext<ReadResourceRequestParams>(new Mock<IMcpServer>().Object) { Params = new() { Uri = "test://static/resource/instanceMethod" } }, new RequestContext<ReadResourceRequestParams>(new Mock<IMcpServer>().Object) { Params = new() { Uri = "test://static/resource/instanceMethod" } },

View file

@ -18,7 +18,7 @@ public partial class McpServerToolTests
Assert.Throws<ArgumentNullException>("function", () => McpServerTool.Create((AIFunction)null!)); Assert.Throws<ArgumentNullException>("function", () => McpServerTool.Create((AIFunction)null!));
Assert.Throws<ArgumentNullException>("method", () => McpServerTool.Create((MethodInfo)null!)); Assert.Throws<ArgumentNullException>("method", () => McpServerTool.Create((MethodInfo)null!));
Assert.Throws<ArgumentNullException>("method", () => McpServerTool.Create((MethodInfo)null!, typeof(object))); Assert.Throws<ArgumentNullException>("method", () => McpServerTool.Create((MethodInfo)null!, typeof(object)));
Assert.Throws<ArgumentNullException>("targetType", () => McpServerTool.Create(typeof(McpServerToolTests).GetMethod(nameof(Create_InvalidArgs_Throws))!, (Type)null!)); Assert.Throws<ArgumentNullException>("createTargetFunc", () => McpServerTool.Create(typeof(McpServerToolTests).GetMethod(nameof(Create_InvalidArgs_Throws))!, null!));
Assert.Throws<ArgumentNullException>("method", () => McpServerTool.Create((Delegate)null!)); Assert.Throws<ArgumentNullException>("method", () => McpServerTool.Create((Delegate)null!));
Assert.NotNull(McpServerTool.Create(typeof(DisposableToolType).GetMethod(nameof(DisposableToolType.InstanceMethod))!, new DisposableToolType())); Assert.NotNull(McpServerTool.Create(typeof(DisposableToolType).GetMethod(nameof(DisposableToolType.InstanceMethod))!, new DisposableToolType()));
@ -129,7 +129,7 @@ public partial class McpServerToolTests
McpServerToolCreateOptions options = new() { SerializerOptions = JsonContext2.Default.Options }; McpServerToolCreateOptions options = new() { SerializerOptions = JsonContext2.Default.Options };
McpServerTool tool1 = McpServerTool.Create( McpServerTool tool1 = McpServerTool.Create(
typeof(DisposableToolType).GetMethod(nameof(DisposableToolType.InstanceMethod))!, typeof(DisposableToolType).GetMethod(nameof(DisposableToolType.InstanceMethod))!,
typeof(DisposableToolType), _ => new DisposableToolType(),
options); options);
var result = await tool1.InvokeAsync( var result = await tool1.InvokeAsync(
@ -144,7 +144,7 @@ public partial class McpServerToolTests
McpServerToolCreateOptions options = new() { SerializerOptions = JsonContext2.Default.Options }; McpServerToolCreateOptions options = new() { SerializerOptions = JsonContext2.Default.Options };
McpServerTool tool1 = McpServerTool.Create( McpServerTool tool1 = McpServerTool.Create(
typeof(AsyncDisposableToolType).GetMethod(nameof(AsyncDisposableToolType.InstanceMethod))!, typeof(AsyncDisposableToolType).GetMethod(nameof(AsyncDisposableToolType.InstanceMethod))!,
typeof(AsyncDisposableToolType), _ => new AsyncDisposableToolType(),
options); options);
var result = await tool1.InvokeAsync( var result = await tool1.InvokeAsync(
@ -163,7 +163,7 @@ public partial class McpServerToolTests
McpServerToolCreateOptions options = new() { SerializerOptions = JsonContext2.Default.Options }; McpServerToolCreateOptions options = new() { SerializerOptions = JsonContext2.Default.Options };
McpServerTool tool1 = McpServerTool.Create( McpServerTool tool1 = McpServerTool.Create(
typeof(AsyncDisposableAndDisposableToolType).GetMethod(nameof(AsyncDisposableAndDisposableToolType.InstanceMethod))!, typeof(AsyncDisposableAndDisposableToolType).GetMethod(nameof(AsyncDisposableAndDisposableToolType.InstanceMethod))!,
typeof(AsyncDisposableAndDisposableToolType), static r => ActivatorUtilities.CreateInstance(r.Services!, typeof(AsyncDisposableAndDisposableToolType)),
options); options);
var result = await tool1.InvokeAsync( var result = await tool1.InvokeAsync(