< Summary

Information
Class: NexusLabs.Needlr.SemanticKernel.SyringeExtensionsForSemanticKernel
Assembly: NexusLabs.Needlr.SemanticKernel
File(s): /home/runner/work/needlr/needlr/src/NexusLabs.Needlr.SemanticKernel/SyringeExtensionsForSemanticKernel.cs
Line coverage
60%
Covered lines: 17
Uncovered lines: 11
Coverable lines: 28
Total lines: 164
Line coverage: 60.7%
Branch coverage
50%
Covered branches: 2
Total branches: 4
Branch coverage: 50%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
UsingSemanticKernel(...)100%11100%
UsingSemanticKernel(...)100%22100%
UsingSemanticKernel(...)0%620%

File(s)

/home/runner/work/needlr/needlr/src/NexusLabs.Needlr.SemanticKernel/SyringeExtensionsForSemanticKernel.cs

#LineLine coverage
 1using Microsoft.Extensions.DependencyInjection;
 2
 3using NexusLabs.Needlr.Injection;
 4
 5using System.Diagnostics.CodeAnalysis;
 6
 7namespace NexusLabs.Needlr.SemanticKernel;
 8
 9/// <summary>
 10/// Extension methods for <see cref="ConfiguredSyringe"/> that enable registering
 11/// Semantic Kernel infrastructure (namely <see cref="IKernelFactory"/>)
 12/// as part of the Needlr build pipeline.
 13/// </summary>
 14/// <remarks>
 15/// <para>
 16/// These helpers defer service registration using the Syringe
 17/// post-plugin registration callback so that plugin discovery and
 18/// registration are completed before the Semantic Kernel factory is added.
 19/// </para>
 20/// <para>
 21/// <strong>Note:</strong> Microsoft.SemanticKernel internally uses reflection to discover
 22/// <c>[KernelFunction]</c> methods and create plugins. This integration therefore requires
 23/// reflection and is not fully AOT-compatible. For AOT scenarios, consider registering
 24/// kernel functions explicitly.
 25/// </para>
 26/// </remarks>
 27public static class SyringeExtensionsForSemanticKernel
 28{
 29    /// <summary>
 30    /// Registers an <see cref="IKernelFactory"/> built via a
 31    /// <see cref="SemanticKernelSyringe"/> instance.
 32    /// </summary>
 33    /// <param name="syringe">
 34    /// The <see cref="ConfiguredSyringe"/> to augment with the registration.
 35    /// </param>
 36    /// <returns>
 37    /// A new <see cref="ConfiguredSyringe"/> instance containing the registration.
 38    /// </returns>
 39    /// <exception cref="ArgumentNullException">
 40    /// Thrown when <paramref name="syringe"/> is <see langword="null"/>.
 41    /// </exception>
 42    /// <remarks>
 43    /// Use this overload when you do not need to configure Semantic Kernel.
 44    /// </remarks>
 45    /// <example>
 46    /// <code>
 47    /// var syringe = new Syringe().UsingReflection().UsingSemanticKernel();
 48    /// </code>
 49    /// </example>
 50    [RequiresUnreferencedCode("Semantic Kernel uses reflection to discover [KernelFunction] methods.")]
 51    [RequiresDynamicCode("Semantic Kernel uses reflection APIs that require dynamic code generation.")]
 52    public static ConfiguredSyringe UsingSemanticKernel(
 53        this ConfiguredSyringe syringe)
 54    {
 1055        ArgumentNullException.ThrowIfNull(syringe);
 1956        return syringe.UsingSemanticKernel(syringe => syringe);
 57    }
 58
 59    /// <summary>
 60    /// Registers an <see cref="IKernelFactory"/> built via a configurable
 61    /// <see cref="SemanticKernelSyringe"/> instance.
 62    /// </summary>
 63    /// <param name="syringe">
 64    /// The <see cref="ConfiguredSyringe"/> to augment with the registration.
 65    /// </param>
 66    /// <param name="configure">
 67    /// A delegate that receives a pre-initialized <see cref="SemanticKernelSyringe"/>
 68    /// (with its <see cref="SemanticKernelSyringe.ServiceProvider"/> set) and
 69    /// returns the configured instance used to build the kernel factory.
 70    /// </param>
 71    /// <returns>
 72    /// A new <see cref="ConfiguredSyringe"/> instance containing the registration.
 73    /// </returns>
 74    /// <exception cref="ArgumentNullException">
 75    /// Thrown when <paramref name="syringe"/> or <paramref name="configure"/> is <see langword="null"/>.
 76    /// </exception>
 77    /// <remarks>
 78    /// Use this overload when your Semantic Kernel configuration needs access to
 79    /// services from the container during configuration.
 80    /// </remarks>
 81    /// <example>
 82    /// <code>
 83    /// var syringe = new Syringe()
 84    ///     .UsingReflection()
 85    ///     .UsingSemanticKernel(sk =&gt; sk with
 86    ///     {
 87    ///         // e.g., add plugins or configure options requiring the provider
 88    ///         PluginTypes = new() { typeof(MyPlugin) },
 89    ///     });
 90    /// </code>
 91    /// </example>
 92    [RequiresUnreferencedCode("Semantic Kernel uses reflection to discover [KernelFunction] methods.")]
 93    [RequiresDynamicCode("Semantic Kernel uses reflection APIs that require dynamic code generation.")]
 94    public static ConfiguredSyringe UsingSemanticKernel(
 95        this ConfiguredSyringe syringe,
 96        Func<SemanticKernelSyringe, SemanticKernelSyringe> configure)
 97    {
 3398        ArgumentNullException.ThrowIfNull(syringe);
 3399        ArgumentNullException.ThrowIfNull(configure);
 100
 33101        return syringe.UsingPostPluginRegistrationCallback(services =>
 33102        {
 32103            services.AddSingleton<IKernelFactory>(provider =>
 32104            {
 32105                SemanticKernelSyringe syringe = new()
 32106                {
 32107                    ServiceProvider = provider,
 32108                };
 32109                syringe = configure.Invoke(syringe);
 32110                var kernelFactory = syringe.BuildKernelFactory();
 32111                return kernelFactory;
 32112            });
 65113        });
 114    }
 115
 116    /// <summary>
 117    /// Registers an <see cref="IKernelFactory"/> built via a <see cref="SemanticKernelSyringe"/>
 118    /// created by the supplied delegate.
 119    /// </summary>
 120    /// <param name="syringe">
 121    /// The <see cref="ConfiguredSyringe"/> to augment with the registration.
 122    /// </param>
 123    /// <param name="configure">
 124    /// A factory that creates a fully-configured <see cref="SemanticKernelSyringe"/>
 125    /// used to build the kernel factory. This is useful when configuration does
 126    /// not need the service provider.
 127    /// </param>
 128    /// <returns>
 129    /// A new <see cref="ConfiguredSyringe"/> instance containing the registration.
 130    /// </returns>
 131    /// <exception cref="ArgumentNullException">
 132    /// Thrown when <paramref name="syringe"/> or <paramref name="configure"/> is <see langword="null"/>.
 133    /// </exception>
 134    /// <example>
 135    /// <code>
 136    /// var syringe = new Syringe()
 137    ///     .UsingReflection()
 138    ///     .UsingSemanticKernel(() =&gt; new SemanticKernelSyringe
 139    ///     {
 140    ///         // Initialize without requiring the service provider
 141    ///         PluginTypes = new() { typeof(MyPlugin) },
 142    ///     });
 143    /// </code>
 144    /// </example>
 145    [RequiresUnreferencedCode("Semantic Kernel uses reflection to discover [KernelFunction] methods.")]
 146    [RequiresDynamicCode("Semantic Kernel uses reflection APIs that require dynamic code generation.")]
 147    public static ConfiguredSyringe UsingSemanticKernel(
 148        this ConfiguredSyringe syringe,
 149        Func<SemanticKernelSyringe> configure)
 150    {
 0151        ArgumentNullException.ThrowIfNull(syringe);
 0152        ArgumentNullException.ThrowIfNull(configure);
 153
 0154        return syringe.UsingPostPluginRegistrationCallback(services =>
 0155        {
 0156            services.AddSingleton<IKernelFactory>(provider =>
 0157            {
 0158                var syringe = configure.Invoke();
 0159                var kernelFactory = syringe.BuildKernelFactory();
 0160                return kernelFactory;
 0161            });
 0162        });
 163    }
 164}