merge(furniture-dal): integrate dal boundary baseline
This commit is contained in:
commit
5a98077e39
14
docs/architecture/dal-domain-alignment.md
Normal file
14
docs/architecture/dal-domain-alignment.md
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
# Furniture DAL Domain Alignment
|
||||||
|
|
||||||
|
## Goal
|
||||||
|
Align DAL with furniture-domain abstractions while keeping DAL technical.
|
||||||
|
|
||||||
|
## DAL Responsibilities
|
||||||
|
- Persistence and retrieval
|
||||||
|
- Technical data translation
|
||||||
|
- Provider/repository boundaries
|
||||||
|
- Contract adaptation for service and domain boundaries without owning decisions
|
||||||
|
|
||||||
|
## Prohibited
|
||||||
|
- Domain decision ownership
|
||||||
|
- Service orchestration concerns
|
||||||
6
docs/migration/dal-port-alignment-map.md
Normal file
6
docs/migration/dal-port-alignment-map.md
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
# DAL Port Alignment Map
|
||||||
|
|
||||||
|
## Alignment Areas
|
||||||
|
- DAL read/write ports map to domain contracts.
|
||||||
|
- Technical DTO translation remains in DAL adapters.
|
||||||
|
- Domain invariants are not reimplemented in DAL.
|
||||||
6
docs/migration/technical-mapping-rules.md
Normal file
6
docs/migration/technical-mapping-rules.md
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
# Technical Mapping Rules
|
||||||
|
|
||||||
|
## Rules
|
||||||
|
- Mapping logic must remain technical and deterministic.
|
||||||
|
- No business branching in DAL mapping layer.
|
||||||
|
- Correlation and metadata pass-through remains unchanged.
|
||||||
@ -0,0 +1,35 @@
|
|||||||
|
using BuildingBlock.Catalog.Contracts.Conventions;
|
||||||
|
using BuildingBlock.Catalog.Contracts.Products;
|
||||||
|
using BuildingBlock.Catalog.Contracts.Responses;
|
||||||
|
using Furniture.DAL.Contracts;
|
||||||
|
|
||||||
|
namespace Furniture.DAL.Adapters;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Default adapter implementation for catalog building block and furniture DAL contracts.
|
||||||
|
/// </summary>
|
||||||
|
public sealed class CatalogProjectionContractAdapter : ICatalogProjectionContractAdapter
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public CatalogProductLookupRequest ToDalRequest(ProductContract contract)
|
||||||
|
{
|
||||||
|
var envelope = new FurnitureDalContractEnvelope(
|
||||||
|
contract.Envelope.ContractVersion,
|
||||||
|
contract.Envelope.CorrelationId);
|
||||||
|
|
||||||
|
return new CatalogProductLookupRequest(envelope, contract.ProductId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public ProductContractResponse ToCatalogResponse(CatalogProductProjectionRecord record)
|
||||||
|
{
|
||||||
|
var envelope = new CatalogContractEnvelope(
|
||||||
|
record.Envelope.ContractVersion,
|
||||||
|
record.Envelope.CorrelationId);
|
||||||
|
|
||||||
|
return new ProductContractResponse(
|
||||||
|
envelope,
|
||||||
|
record.ProductId,
|
||||||
|
record.DisplayName);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,40 @@
|
|||||||
|
using Core.Blueprint.Common.Runtime;
|
||||||
|
using Furniture.DAL.Contracts;
|
||||||
|
using Furniture.DAL.Grpc;
|
||||||
|
|
||||||
|
namespace Furniture.DAL.Adapters;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Default adapter implementation for furniture DAL gRPC contract translation.
|
||||||
|
/// </summary>
|
||||||
|
public sealed class FurnitureDalGrpcContractAdapter(IBlueprintSystemClock clock) : IFurnitureDalGrpcContractAdapter
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public FurnitureAvailabilityDalGrpcContract ToGrpcAvailabilityRequest(FurnitureAvailabilityLookupRequest request)
|
||||||
|
{
|
||||||
|
return new FurnitureAvailabilityDalGrpcContract(request.FurnitureId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public FurnitureAvailabilityLookupRequest FromGrpcAvailabilityRequest(FurnitureAvailabilityDalGrpcContract contract)
|
||||||
|
{
|
||||||
|
return new FurnitureAvailabilityLookupRequest(CreateEnvelope(), contract.FurnitureId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public CatalogProductDalGrpcContract ToGrpcCatalogRequest(CatalogProductLookupRequest request)
|
||||||
|
{
|
||||||
|
return new CatalogProductDalGrpcContract(request.ProductId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public CatalogProductLookupRequest FromGrpcCatalogRequest(CatalogProductDalGrpcContract contract)
|
||||||
|
{
|
||||||
|
return new CatalogProductLookupRequest(CreateEnvelope(), contract.ProductId);
|
||||||
|
}
|
||||||
|
|
||||||
|
private FurnitureDalContractEnvelope CreateEnvelope()
|
||||||
|
{
|
||||||
|
return new FurnitureDalContractEnvelope("1.0.0", $"corr-{clock.UtcNow:yyyyMMddHHmmssfff}");
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,24 @@
|
|||||||
|
using Furniture.DAL.Contracts;
|
||||||
|
|
||||||
|
namespace Furniture.DAL.Caching;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Default cache invalidation policy for furniture DAL runtime.
|
||||||
|
/// </summary>
|
||||||
|
public sealed class FurnitureCacheInvalidationPolicy : ICacheInvalidationPolicy
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public string BuildAvailabilityKey(FurnitureAvailabilityLookupRequest request)
|
||||||
|
{
|
||||||
|
return $"furniture:availability:{request.FurnitureId}";
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public IReadOnlyList<string> ResolveInvalidationKeys(FurnitureCacheInvalidationRequest request)
|
||||||
|
{
|
||||||
|
return
|
||||||
|
[
|
||||||
|
$"furniture:availability:{request.FurnitureId}"
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
12
src/Furniture.DAL/Contracts/DalDependencyHealthStatus.cs
Normal file
12
src/Furniture.DAL/Contracts/DalDependencyHealthStatus.cs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
namespace Furniture.DAL.Contracts;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Response contract for furniture DAL dependency health evaluation.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="Envelope">Contract envelope metadata.</param>
|
||||||
|
/// <param name="IsHealthy">Indicates whether all runtime dependencies are healthy.</param>
|
||||||
|
/// <param name="DependencyNames">Dependency names included in health evaluation.</param>
|
||||||
|
public sealed record DalDependencyHealthStatus(
|
||||||
|
FurnitureDalContractEnvelope Envelope,
|
||||||
|
bool IsHealthy,
|
||||||
|
IReadOnlyList<string> DependencyNames);
|
||||||
@ -0,0 +1,40 @@
|
|||||||
|
using Core.Blueprint.Common.DependencyInjection;
|
||||||
|
using Furniture.DAL.Adapters;
|
||||||
|
using Furniture.DAL.Caching;
|
||||||
|
using Furniture.DAL.Health;
|
||||||
|
using Furniture.DAL.Providers;
|
||||||
|
using Furniture.DAL.Providers.InMemory;
|
||||||
|
using Furniture.DAL.Repositories;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||||
|
|
||||||
|
namespace Furniture.DAL.DependencyInjection;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Registers furniture DAL runtime provider, repository, and adapter implementations.
|
||||||
|
/// </summary>
|
||||||
|
public static class FurnitureDalServiceCollectionExtensions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Adds furniture DAL runtime implementations aligned with blueprint runtime core.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="services">Service collection.</param>
|
||||||
|
/// <returns>Service collection for fluent chaining.</returns>
|
||||||
|
public static IServiceCollection AddFurnitureDalRuntime(this IServiceCollection services)
|
||||||
|
{
|
||||||
|
services.AddBlueprintRuntimeCore();
|
||||||
|
|
||||||
|
services.TryAddSingleton<IFurnitureDataProvider, InMemoryFurnitureDataProvider>();
|
||||||
|
services.TryAddSingleton<ICatalogDataProvider, InMemoryCatalogDataProvider>();
|
||||||
|
|
||||||
|
services.TryAddSingleton<ICacheInvalidationPolicy, FurnitureCacheInvalidationPolicy>();
|
||||||
|
services.TryAddSingleton<IFurnitureRepository, FurnitureRepository>();
|
||||||
|
services.TryAddSingleton<ICatalogRepository, CatalogRepository>();
|
||||||
|
|
||||||
|
services.TryAddSingleton<ICatalogProjectionContractAdapter, CatalogProjectionContractAdapter>();
|
||||||
|
services.TryAddSingleton<IFurnitureDalGrpcContractAdapter, FurnitureDalGrpcContractAdapter>();
|
||||||
|
services.TryAddSingleton<IDalDependencyHealthCheck, DalDependencyHealthCheck>();
|
||||||
|
|
||||||
|
return services;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -5,6 +5,7 @@
|
|||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="10.0.0" />
|
||||||
<ProjectReference Include="..\..\..\blueprint-platform\src\Core.Blueprint.Common\Core.Blueprint.Common.csproj" />
|
<ProjectReference Include="..\..\..\blueprint-platform\src\Core.Blueprint.Common\Core.Blueprint.Common.csproj" />
|
||||||
<ProjectReference Include="..\..\..\building-block-catalog\src\BuildingBlock.Catalog.Contracts\BuildingBlock.Catalog.Contracts.csproj" />
|
<ProjectReference Include="..\..\..\building-block-catalog\src\BuildingBlock.Catalog.Contracts\BuildingBlock.Catalog.Contracts.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|||||||
27
src/Furniture.DAL/Health/DalDependencyHealthCheck.cs
Normal file
27
src/Furniture.DAL/Health/DalDependencyHealthCheck.cs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
using Core.Blueprint.Common.Runtime;
|
||||||
|
using Furniture.DAL.Contracts;
|
||||||
|
|
||||||
|
namespace Furniture.DAL.Health;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Default DAL dependency health check implementation.
|
||||||
|
/// </summary>
|
||||||
|
public sealed class DalDependencyHealthCheck(IBlueprintSystemClock clock) : IDalDependencyHealthCheck
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public Task<DalDependencyHealthStatus> CheckAsync(CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
var envelope = new FurnitureDalContractEnvelope("1.0.0", $"corr-{clock.UtcNow:yyyyMMddHHmmssfff}");
|
||||||
|
IReadOnlyList<string> dependencyNames =
|
||||||
|
[
|
||||||
|
"IFurnitureDataProvider",
|
||||||
|
"ICatalogDataProvider",
|
||||||
|
"IFurnitureRepository",
|
||||||
|
"ICatalogRepository",
|
||||||
|
"ICacheInvalidationPolicy"
|
||||||
|
];
|
||||||
|
|
||||||
|
var status = new DalDependencyHealthStatus(envelope, true, dependencyNames);
|
||||||
|
return Task.FromResult(status);
|
||||||
|
}
|
||||||
|
}
|
||||||
16
src/Furniture.DAL/Health/IDalDependencyHealthCheck.cs
Normal file
16
src/Furniture.DAL/Health/IDalDependencyHealthCheck.cs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
using Furniture.DAL.Contracts;
|
||||||
|
|
||||||
|
namespace Furniture.DAL.Health;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Defines furniture DAL dependency health check boundary.
|
||||||
|
/// </summary>
|
||||||
|
public interface IDalDependencyHealthCheck
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Evaluates runtime dependency health for DAL providers and repositories.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="cancellationToken">Cancellation token.</param>
|
||||||
|
/// <returns>Dependency health status contract.</returns>
|
||||||
|
Task<DalDependencyHealthStatus> CheckAsync(CancellationToken cancellationToken = default);
|
||||||
|
}
|
||||||
@ -0,0 +1,35 @@
|
|||||||
|
using Furniture.DAL.Contracts;
|
||||||
|
|
||||||
|
namespace Furniture.DAL.Providers.InMemory;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// In-memory provider implementation for catalog persistence reads.
|
||||||
|
/// </summary>
|
||||||
|
public sealed class InMemoryCatalogDataProvider : ICatalogDataProvider
|
||||||
|
{
|
||||||
|
private static readonly IReadOnlyDictionary<string, string> DisplayNameByProductId =
|
||||||
|
new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
|
||||||
|
{
|
||||||
|
["PRD-001"] = "Contoso Lounge Chair",
|
||||||
|
["PRD-002"] = "Fabrikam Office Desk",
|
||||||
|
["PRD-003"] = "Northwind Shelf"
|
||||||
|
};
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public Task<CatalogProductProjectionRecord?> ReadProductAsync(
|
||||||
|
CatalogProductLookupRequest request,
|
||||||
|
CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
if (!DisplayNameByProductId.TryGetValue(request.ProductId, out var displayName))
|
||||||
|
{
|
||||||
|
return Task.FromResult<CatalogProductProjectionRecord?>(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
var record = new CatalogProductProjectionRecord(
|
||||||
|
request.Envelope,
|
||||||
|
request.ProductId,
|
||||||
|
displayName);
|
||||||
|
|
||||||
|
return Task.FromResult<CatalogProductProjectionRecord?>(record);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,35 @@
|
|||||||
|
using Furniture.DAL.Contracts;
|
||||||
|
|
||||||
|
namespace Furniture.DAL.Providers.InMemory;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// In-memory provider implementation for furniture persistence reads.
|
||||||
|
/// </summary>
|
||||||
|
public sealed class InMemoryFurnitureDataProvider : IFurnitureDataProvider
|
||||||
|
{
|
||||||
|
private static readonly IReadOnlyDictionary<string, int> AvailabilityByFurnitureId =
|
||||||
|
new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase)
|
||||||
|
{
|
||||||
|
["FUR-001"] = 8,
|
||||||
|
["FUR-002"] = 2,
|
||||||
|
["FUR-003"] = 0
|
||||||
|
};
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public Task<FurnitureAvailabilityRecord?> ReadAvailabilityAsync(
|
||||||
|
FurnitureAvailabilityLookupRequest request,
|
||||||
|
CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
if (!AvailabilityByFurnitureId.TryGetValue(request.FurnitureId, out var quantityAvailable))
|
||||||
|
{
|
||||||
|
return Task.FromResult<FurnitureAvailabilityRecord?>(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
var record = new FurnitureAvailabilityRecord(
|
||||||
|
request.Envelope,
|
||||||
|
request.FurnitureId,
|
||||||
|
quantityAvailable);
|
||||||
|
|
||||||
|
return Task.FromResult<FurnitureAvailabilityRecord?>(record);
|
||||||
|
}
|
||||||
|
}
|
||||||
18
src/Furniture.DAL/Repositories/CatalogRepository.cs
Normal file
18
src/Furniture.DAL/Repositories/CatalogRepository.cs
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
using Furniture.DAL.Contracts;
|
||||||
|
using Furniture.DAL.Providers;
|
||||||
|
|
||||||
|
namespace Furniture.DAL.Repositories;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Default catalog repository implementation composed from DAL providers.
|
||||||
|
/// </summary>
|
||||||
|
public sealed class CatalogRepository(ICatalogDataProvider catalogDataProvider) : ICatalogRepository
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public Task<CatalogProductProjectionRecord?> ReadProductAsync(
|
||||||
|
CatalogProductLookupRequest request,
|
||||||
|
CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
return catalogDataProvider.ReadProductAsync(request, cancellationToken);
|
||||||
|
}
|
||||||
|
}
|
||||||
38
src/Furniture.DAL/Repositories/FurnitureRepository.cs
Normal file
38
src/Furniture.DAL/Repositories/FurnitureRepository.cs
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
using System.Collections.Concurrent;
|
||||||
|
using Furniture.DAL.Caching;
|
||||||
|
using Furniture.DAL.Contracts;
|
||||||
|
using Furniture.DAL.Providers;
|
||||||
|
|
||||||
|
namespace Furniture.DAL.Repositories;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Default furniture repository implementation composed from DAL providers.
|
||||||
|
/// </summary>
|
||||||
|
public sealed class FurnitureRepository(
|
||||||
|
IFurnitureDataProvider furnitureDataProvider,
|
||||||
|
ICacheInvalidationPolicy cacheInvalidationPolicy) : IFurnitureRepository
|
||||||
|
{
|
||||||
|
private readonly ConcurrentDictionary<string, FurnitureAvailabilityRecord> availabilityCache = new(
|
||||||
|
StringComparer.OrdinalIgnoreCase);
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public async Task<FurnitureAvailabilityRecord?> ReadAvailabilityAsync(
|
||||||
|
FurnitureAvailabilityLookupRequest request,
|
||||||
|
CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
var cacheKey = cacheInvalidationPolicy.BuildAvailabilityKey(request);
|
||||||
|
if (availabilityCache.TryGetValue(cacheKey, out var cachedRecord))
|
||||||
|
{
|
||||||
|
return cachedRecord with { Envelope = request.Envelope };
|
||||||
|
}
|
||||||
|
|
||||||
|
var providerRecord = await furnitureDataProvider.ReadAvailabilityAsync(request, cancellationToken);
|
||||||
|
if (providerRecord is null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
availabilityCache[cacheKey] = providerRecord;
|
||||||
|
return providerRecord;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -7,6 +7,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="coverlet.collector" Version="6.0.4" />
|
<PackageReference Include="coverlet.collector" Version="6.0.4" />
|
||||||
|
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="10.0.0" />
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.1" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.1" />
|
||||||
<PackageReference Include="xunit" Version="2.9.3" />
|
<PackageReference Include="xunit" Version="2.9.3" />
|
||||||
<PackageReference Include="xunit.runner.visualstudio" Version="3.1.4" />
|
<PackageReference Include="xunit.runner.visualstudio" Version="3.1.4" />
|
||||||
|
|||||||
76
tests/Furniture.DAL.UnitTests/RuntimeWiringTests.cs
Normal file
76
tests/Furniture.DAL.UnitTests/RuntimeWiringTests.cs
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
using Furniture.DAL.Adapters;
|
||||||
|
using Furniture.DAL.Contracts;
|
||||||
|
using Furniture.DAL.DependencyInjection;
|
||||||
|
using Furniture.DAL.Health;
|
||||||
|
using Furniture.DAL.Repositories;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
|
namespace Furniture.DAL.UnitTests;
|
||||||
|
|
||||||
|
public class RuntimeWiringTests
|
||||||
|
{
|
||||||
|
[Fact]
|
||||||
|
public async Task AddFurnitureDalRuntime_WhenResolved_WiresRepositoriesAndProviders()
|
||||||
|
{
|
||||||
|
var services = new ServiceCollection();
|
||||||
|
services.AddFurnitureDalRuntime();
|
||||||
|
|
||||||
|
using var provider = services.BuildServiceProvider();
|
||||||
|
var furnitureRepository = provider.GetRequiredService<IFurnitureRepository>();
|
||||||
|
var catalogRepository = provider.GetRequiredService<ICatalogRepository>();
|
||||||
|
var envelope = new FurnitureDalContractEnvelope("1.0.0", "corr-123");
|
||||||
|
|
||||||
|
var availability = await furnitureRepository.ReadAvailabilityAsync(
|
||||||
|
new FurnitureAvailabilityLookupRequest(envelope, "FUR-001"));
|
||||||
|
var product = await catalogRepository.ReadProductAsync(
|
||||||
|
new CatalogProductLookupRequest(envelope, "PRD-001"));
|
||||||
|
|
||||||
|
Assert.NotNull(availability);
|
||||||
|
Assert.Equal("FUR-001", availability.FurnitureId);
|
||||||
|
Assert.Equal(8, availability.QuantityAvailable);
|
||||||
|
|
||||||
|
Assert.NotNull(product);
|
||||||
|
Assert.Equal("PRD-001", product.ProductId);
|
||||||
|
Assert.Equal("Contoso Lounge Chair", product.DisplayName);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void AddFurnitureDalRuntime_WhenResolved_WiresGrpcAndCatalogAdapters()
|
||||||
|
{
|
||||||
|
var services = new ServiceCollection();
|
||||||
|
services.AddFurnitureDalRuntime();
|
||||||
|
|
||||||
|
using var provider = services.BuildServiceProvider();
|
||||||
|
var grpcAdapter = provider.GetRequiredService<IFurnitureDalGrpcContractAdapter>();
|
||||||
|
var projectionAdapter = provider.GetRequiredService<ICatalogProjectionContractAdapter>();
|
||||||
|
|
||||||
|
var availabilityRequest = grpcAdapter.FromGrpcAvailabilityRequest(
|
||||||
|
new Furniture.DAL.Grpc.FurnitureAvailabilityDalGrpcContract("FUR-002"));
|
||||||
|
var catalogRequest = projectionAdapter.ToDalRequest(
|
||||||
|
new BuildingBlock.Catalog.Contracts.Products.ProductContract(
|
||||||
|
new BuildingBlock.Catalog.Contracts.Conventions.CatalogContractEnvelope("1.0.0", "corr-456"),
|
||||||
|
"PRD-002",
|
||||||
|
"Fabrikam Office Desk"));
|
||||||
|
|
||||||
|
Assert.Equal("FUR-002", availabilityRequest.FurnitureId);
|
||||||
|
Assert.NotEmpty(availabilityRequest.Envelope.CorrelationId);
|
||||||
|
Assert.Equal("PRD-002", catalogRequest.ProductId);
|
||||||
|
Assert.Equal("corr-456", catalogRequest.Envelope.CorrelationId);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task AddFurnitureDalRuntime_WhenResolved_WiresDependencyHealthCheck()
|
||||||
|
{
|
||||||
|
var services = new ServiceCollection();
|
||||||
|
services.AddFurnitureDalRuntime();
|
||||||
|
|
||||||
|
using var provider = services.BuildServiceProvider();
|
||||||
|
var healthCheck = provider.GetRequiredService<IDalDependencyHealthCheck>();
|
||||||
|
|
||||||
|
var status = await healthCheck.CheckAsync();
|
||||||
|
|
||||||
|
Assert.True(status.IsHealthy);
|
||||||
|
Assert.Contains("IFurnitureDataProvider", status.DependencyNames);
|
||||||
|
Assert.Contains("ICatalogRepository", status.DependencyNames);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user