using Domain;
using Saritasa.Tools.Messages.Abstractions.Queries;
namespace DataAccess
{
[QueryHandlers]
public class StringQueries : IStringQueries
{
public string GetString()
{
return "test";
}
}
}
namespace DataAccess
{
public class IntegerQueries
{
public int GetNumber()
{
return 42;
}
}
}
using DataAccess;
using Domain;
using Microsoft.Extensions.DependencyInjection;
using Saritasa.Tools.Messages.Abstractions;
using Saritasa.Tools.Messages.Common;
using Saritasa.Tools.Messages.Queries;
using Saritasa.Tools.Messages.Queries.PipelineMiddlewares;
using System;
using System.Reflection;
internal class Program
{
private static void Main(string[] args)
{
var p = new Program();
p.Test1();
p.Test2();
p.Test3();
}
private void Test1()
{
var sp = Prepare1();
Run1(sp); // System.InvalidOperationException: 'Query object of type DataAccess.StringQueries cannot be resolved.'
}
private void Test2()
{
var sp = Prepare2();
Run1(sp); // Works.
Run2(sp); // Works.
Run3(sp); // Works.
}
private void Test3()
{
var sp = Prepare3();
Run1(sp); // System.InvalidOperationException: 'Cannot find implementation for query with type Domain.IStringQueries.'
Run2(sp); // Works.
Run3(sp); // Works.
}
private IServiceProvider Prepare1()
{
var services = new ServiceCollection();
services.AddTransient<IStringQueries, StringQueries>();
return RegisterPipeline(services, typeof(StringQueries).GetTypeInfo().Assembly);
}
private IServiceProvider Prepare2()
{
var services = new ServiceCollection();
services.AddTransient<StringQueries>();
services.AddTransient<IntegerQueries>();
return RegisterPipeline(services, typeof(StringQueries).GetTypeInfo().Assembly);
}
private IServiceProvider Prepare3()
{
var services = new ServiceCollection();
services.AddTransient<StringQueries>();
services.AddTransient<IntegerQueries>();
return RegisterPipeline(services);
}
private IServiceProvider RegisterPipeline(IServiceCollection services, params Assembly[] assemblies)
{
var pipelineContainer = new DefaultMessagePipelineContainer();
pipelineContainer.AddQueryPipeline()
.AddMiddleware(new QueryObjectResolverMiddleware(assemblies) { UseInternalObjectResolver = false })
.AddMiddleware(new QueryExecutorMiddleware())
.AddMiddleware(new QueryObjectReleaseMiddleware());
services.AddSingleton<IMessagePipelineContainer>(pipelineContainer);
services.AddScoped<IMessagePipelineService, DefaultMessagePipelineService>();
return services.BuildServiceProvider();
}
private void Run1(IServiceProvider serviceProvider)
{
var pipeline = serviceProvider.GetRequiredService<IMessagePipelineService>();
var result = pipeline.Query<IStringQueries>().With(q => q.GetString());
Console.WriteLine(result);
}
private void Run2(IServiceProvider serviceProvider)
{
var pipeline = serviceProvider.GetRequiredService<IMessagePipelineService>();
var result = pipeline.Query<StringQueries>().With(q => q.GetString());
Console.WriteLine(result);
}
private void Run3(IServiceProvider serviceProvider)
{
var pipeline = serviceProvider.GetRequiredService<IMessagePipelineService>();
var result = pipeline.Query<IntegerQueries>().With(q => q.GetNumber());
Console.WriteLine(result);
}
}
Query pipeline does not resolve query handler correctly when interface is used
UseInternalObjectResolver is false in all tests.
pipeline.Query<SomeClass>
works always.pipeline.Query<ISomeInterface>
works only if 3 conditions are met: