Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 66 additions & 0 deletions src/Libraries/ACATCore.Tests.Configuration/CQRSPatternTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@
using ACAT.Core.Configuration;
using ACAT.Core.Patterns.CQRS;
using ACAT.Core.Patterns.CQRS.Samples;
using ACAT.Core.PanelManagement;
using ACAT.Core.PanelManagement.Common;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;

Expand Down Expand Up @@ -222,5 +224,69 @@ public void GetActiveAgentNameQueryHandler_ReturnsEmptyStringWhenNoAgent()

Assert.AreEqual(string.Empty, result);
}

// ----------------------------------------------------------------
// AgentManagerExtensions.GetCurrentAgentNameViaQuery – behaviour
// ----------------------------------------------------------------

[TestCleanup]
public void ResetServiceProvider()
{
// Ensure Context.ServiceProvider is reset after every test so
// that DI-enabled tests do not leak state into subsequent tests.
Context.ServiceProvider = null;
}

[TestMethod]
public void GetCurrentAgentNameViaQuery_WithoutServiceProvider_FallsBackToDirectCall()
{
Context.ServiceProvider = null;
var fake = new FakeAgentManager { CurrentAgentName = "FallbackAgent" };

string result = fake.GetCurrentAgentNameViaQuery();

Assert.AreEqual("FallbackAgent", result);
}

[TestMethod]
public void GetCurrentAgentNameViaQuery_WithoutServiceProvider_NullAgentName_ReturnsEmpty()
{
Context.ServiceProvider = null;
var fake = new FakeAgentManager { CurrentAgentName = null };

string result = fake.GetCurrentAgentNameViaQuery();

Assert.AreEqual(string.Empty, result);
}

[TestMethod]
public void GetCurrentAgentNameViaQuery_WithServiceProvider_RoutesViaHandler()
{
var fake = new FakeAgentManager { CurrentAgentName = "DirectAgent" };
var services = new ServiceCollection();
// Register a handler backed by a *different* fake so we can prove
// the call was routed through the DI handler and not the direct path.
var handlerFake = new FakeAgentManager { CurrentAgentName = "HandlerAgent" };
services.AddTransient<IQueryHandler<GetActiveAgentNameQuery, string>>(
_ => new GetActiveAgentNameQueryHandler(handlerFake));
Context.ServiceProvider = services.BuildServiceProvider();

string result = fake.GetCurrentAgentNameViaQuery();

Assert.AreEqual("HandlerAgent", result);
}

[TestMethod]
public void GetCurrentAgentNameViaQuery_WithServiceProvider_NoHandlerRegistered_FallsBackToDirectCall()
{
var fake = new FakeAgentManager { CurrentAgentName = "DirectFallback" };
// Build a DI container that does NOT register the query handler.
var services = new ServiceCollection();
Context.ServiceProvider = services.BuildServiceProvider();

string result = fake.GetCurrentAgentNameViaQuery();

Assert.AreEqual("DirectFallback", result);
}
}
}
1 change: 1 addition & 0 deletions src/Libraries/ACATCore/ACAT.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -593,6 +593,7 @@
<Compile Include="Patterns\CQRS\Samples\GetConfigurationValueQueryHandler.cs" />
<Compile Include="Patterns\CQRS\Samples\GetActiveAgentNameQuery.cs" />
<Compile Include="Patterns\CQRS\Samples\GetActiveAgentNameQueryHandler.cs" />
<Compile Include="Patterns\CQRS\AgentManagerExtensions.cs" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="ActuatorManagement\UI\ActuatorErrorForm.resx">
Expand Down
74 changes: 74 additions & 0 deletions src/Libraries/ACATCore/Patterns/CQRS/AgentManagerExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
////////////////////////////////////////////////////////////////////////////
//
// Copyright 2013-2019; 2023 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
//
// AgentManagerExtensions.cs
//
// Extension methods for IAgentManager that provide CQRS-based wrappers
// around agent query operations. Each method resolves the registered
// IQueryHandler from the DI container when available and falls back to
// calling the IAgentManager method directly when running outside a
// DI-configured environment (e.g., unit tests or legacy entry points).
//
// Usage – call-site migration:
//
// Before:
// string name = Context.AppAgentMgr.GetCurrentAgentName();
//
// After:
// string name = Context.AppAgentMgr.GetCurrentAgentNameViaQuery();
//
// The extension method body can be simplified to the CQRS-only path once
// every call site has been migrated and legacy fallback is no longer needed.
//
////////////////////////////////////////////////////////////////////////////

using ACAT.Core.AgentManagement;
using ACAT.Core.PanelManagement;
using ACAT.Core.Patterns.CQRS.Samples;

namespace ACAT.Core.Patterns.CQRS
{
/// <summary>
/// Extension methods for <see cref="IAgentManager"/> that route agent
/// queries through the CQRS <see cref="IQueryHandler{TQuery,TResult}"/>
/// infrastructure when available, falling back to direct
/// <see cref="IAgentManager"/> calls when a DI container is not configured.
/// </summary>
public static class AgentManagerExtensions
{
/// <summary>
/// Returns the name of the currently active agent by dispatching a
/// <see cref="GetActiveAgentNameQuery"/> through the registered
/// <see cref="IQueryHandler{TQuery,TResult}"/>.
/// </summary>
/// <remarks>
/// When <see cref="Context.ServiceProvider"/> is configured the call
/// is routed through the DI-registered handler so that the CQRS
/// boundary is respected. When no provider is available the method
/// falls back to <see cref="IAgentManager.GetCurrentAgentName"/> and
/// normalises a <see langword="null"/> return to
/// <see cref="string.Empty"/>.
/// </remarks>
/// <param name="agentManager">The agent manager to query.</param>
/// <returns>
/// The name of the active agent, or <see cref="string.Empty"/> when
/// no agent is currently active.
/// </returns>
public static string GetCurrentAgentNameViaQuery(this IAgentManager agentManager)
{
var handler = Context.ServiceProvider
?.GetService(typeof(IQueryHandler<GetActiveAgentNameQuery, string>))
as IQueryHandler<GetActiveAgentNameQuery, string>;

if (handler != null)
{
return handler.Handle(new GetActiveAgentNameQuery());
}

return agentManager.GetCurrentAgentName() ?? string.Empty;
}
}
}