Skip to content

awright18/Darker

 
 

Repository files navigation

Darker

The query-side counterpart of Brighter.

Build status NuGet

Usage with ASP.NET Core

In your ConfigureServices method, use AddDarker to add Darker to the container. ASP.NET Core integration is provided by the Paramore.Darker.AspNetCore package.

// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
    // Add Darker and some extensions.
    services.AddDarker(opts =>
        {
            opts.DiscoverQueriesAndHandlersFromAssemblies = new[] { typeof(GetPeopleQuery).Assembly };
        })
        .AddJsonQueryLogging()
        .AddDefaultPolicies();

    // Add framework services.
    services.AddMvc();
}

This example uses the request logging integration provided by Paramore.Darker.QueryLogging and policy integration provided by Paramore.Darker.Policies. Have a look at the Startup.ConfigureServices method in the SampleApi project for more examples on how to use the integrations.

Inject IQueryProcessor and call Execute or ExecuteAsync to dispatch your query to the registered query handler.

using Paramore.Darker;
using Microsoft.AspNetCore.Mvc;
using System.Threading;
using System.Threading.Tasks;

public class FooController : ControllerBase
{
    private readonly IQueryProcessor _queryProcessor;

    public FooController(IQueryProcessor queryProcessor)
    {
        _queryProcessor = queryProcessor;
    }

    public async Task<IActionResult> Get(CancellationToken cancellationToken = default(CancellationToken))
    {
        var query = new FooQuery();
        var result = await _queryProcessor.ExecuteAsync(query, cancellationToken);

        return Ok(result.Answer);
    }
}
using Paramore.Darker;

public sealed class FooQuery : IQuery<FooQuery.Result>
{
    public int Number { get; }

    public FooQuery(int number)
    {
        Number = number;
    }

    public sealed class Result
    {
        public string Answer { get; }

        public Result(string answer)
        {
            Answer = answer;
        }
    }
}

Implement either QueryHandler<,> or AsyncQueryHandler<,> depending on whether you wish to execute your queries synchronously or asynchronously. For most control, you can also implement IQueryHandler<,> directly.

using Paramore.Darker;
using Paramore.Darker.Attributes;
using Paramore.Darker.Policies;
using Paramore.Darker.QueryLogging;
using System.Threading;
using System.Threading.Tasks;

public sealed class FooQueryHandler : AsyncQueryHandler<FooQuery, FooQuery.Result>
{
    [QueryLogging(1)]
    [FallbackPolicy(2)]
    [RetryableQuery(3)]
    public override async Task<FooQuery.Result> ExecuteAsync(FooQuery query, CancellationToken cancellationToken = default(CancellationToken))
    {
        var answer = await CalculateAnswerForNumber(query.Number, cancellationToken).ConfigureAwait(false);
        return new FooQuery.Result(answer);
    }
}

Usage without ASP.NET

Register your queries and handlers with QueryHandlerRegistry and use QueryProcessorBuilder to configure and build a IQueryProcessor.

var registry = new QueryHandlerRegistry();
registry.Register<FooQuery, FooQuery.Result, FooQueryHandler>();

IQueryProcessor queryProcessor = QueryProcessorBuilder.With()
    .Handlers(registry, Activator.CreateInstance, t => {}, Activator.CreateInstance)
    .InMemoryQueryContextFactory()
    .Build();

Instead of Activator.CreateInstance, you can pass any factory Func<Type, object> to constuct handlers and decorator. Integrations with some DI frameworks are available, for example SimpleInjector, as provided by the Paramore.Darker.SimpleInjector package:

var container = new Container();

var queryProcessor = QueryProcessorBuilder.With()
    .SimpleInjectoHandlers(container, opts =>
        opts.WithQueriesAndHandlersFromAssembly(typeof(GetPeopleQuery).Assembly))
    .InMemoryQueryContextFactory()
    .Build();

container.Register<IQueryProcessor>(queryProcessor);

In this case you don't need to manually register queries or handlers as the integration allows scanning assemblies for matching types.

About

The query-side counterpart of Brighter

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • C# 99.3%
  • PowerShell 0.7%