Incremental work on trigger API

This commit is contained in:
Sipke Schoorstra 2020-10-17 12:49:41 +02:00
parent c11cb383b5
commit 8423fde504
36 changed files with 264 additions and 61 deletions

View file

@ -36,11 +36,12 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.DataProtection" Version="3.1.7" />
<PackageReference Include="Microsoft.AspNetCore.DataProtection" Version="3.1.9" />
<PackageReference Include="Microsoft.AspNetCore.Http" Version="2.2.2" />
<PackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="2.2.5" />
<PackageReference Include="Microsoft.Extensions.Http" Version="3.1.7" />
<PackageReference Include="Microsoft.Extensions.Http" Version="3.1.9" />
<PackageReference Include="Open.Linq.AsyncExtensions" Version="1.2.0" />
</ItemGroup>
</Project>

View file

@ -5,8 +5,10 @@ using Elsa.Activities.Http.Options;
using Elsa.Activities.Http.Parsers;
using Elsa.Activities.Http.RequestHandlers.Handlers;
using Elsa.Activities.Http.Services;
using Elsa.Activities.Http.Triggers;
using Elsa.Data;
using Elsa.Extensions;
using Elsa.Triggers;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Infrastructure;
using Microsoft.Extensions.DependencyInjection.Extensions;
@ -38,6 +40,7 @@ namespace Microsoft.Extensions.DependencyInjection
.AddSingleton<IHttpResponseBodyParser, JsonHttpResponseBodyParser>()
.AddSingleton<IActionContextAccessor, ActionContextAccessor>()
.AddSingleton<IAbsoluteUrlProvider, DefaultAbsoluteUrlProvider>()
.AddSingleton<ITriggerProvider, ReceiveHttpRequestTriggerProvider>()
.AddIndexProvider<WorkflowInstanceByReceiveHttpRequestIndexProvider>()
.AddDataMigration<Migrations>()
.AddHttpContextAccessor()

View file

@ -1,24 +1,38 @@
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Elsa.Activities.Http.Services;
using Elsa.Activities.Http.Triggers;
using Elsa.Services;
using Elsa.Triggers;
using Microsoft.AspNetCore.Http;
namespace Elsa.Activities.Http.Middleware
{
public class RequestHandlerMiddleware<THandler> where THandler : IRequestHandler
public class ReceiveHttpRequestMiddleware
{
private readonly RequestDelegate _next;
public RequestHandlerMiddleware(RequestDelegate next)
public ReceiveHttpRequestMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task InvokeAsync(HttpContext httpContext, THandler handler)
public async Task InvokeAsync(HttpContext httpContext, IWorkflowSelector workflowSelector, IWorkflowHost workflowHost, CancellationToken cancellationToken)
{
var result = await handler.HandleRequestAsync();
var path = httpContext.Request.Path;
var method = httpContext.Request.Method;
var results = await workflowSelector.SelectWorkflowsAsync<ReceiveHttpRequestTrigger>(
x => x.Path == path && x.Method == null || x.Method == method,
cancellationToken).ToListAsync(cancellationToken);
if (result != null && !httpContext.Response.HasStarted)
await result.ExecuteResultAsync(httpContext, _next);
var result = results.FirstOrDefault();
if (result == null)
await _next(httpContext);
else
await workflowHost.RunWorkflowAsync(result.WorkflowBlueprint, result.ActivityId, cancellationToken: cancellationToken);
}
}
}

View file

@ -0,0 +1,59 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Security.Cryptography.Xml;
using System.Threading;
using System.Threading.Tasks;
using Elsa.Expressions;
using Elsa.Services;
using Elsa.Services.Models;
using Elsa.Triggers;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
namespace Elsa.Activities.Http.Triggers
{
public class ReceiveHttpRequestTrigger : ITrigger
{
public PathString Path { get; set; }
public string? Method { get; set; }
public string ActivityId { get; set; }
}
public class ReceiveHttpRequestTriggerProvider : TriggerProvider<ReceiveHttpRequestTrigger>
{
private readonly IServiceProvider _serviceProvider;
private readonly IWorkflowFactory _workflowFactory;
public ReceiveHttpRequestTriggerProvider(IServiceProvider serviceProvider, IWorkflowFactory workflowFactory)
{
_serviceProvider = serviceProvider;
_workflowFactory = workflowFactory;
}
public override async IAsyncEnumerable<ITrigger> GetTriggersAsync(IWorkflowBlueprint workflowBlueprint, [EnumeratorCancellation] CancellationToken cancellationToken = default)
{
var httpRequestActivities = workflowBlueprint
.GetStartActivities()
.Where(x => x.Type == nameof(ReceiveHttpRequest))
.ToList();
using var scope = _serviceProvider.CreateScope();
var workflowInstance = await _workflowFactory.InstantiateAsync(workflowBlueprint, cancellationToken: cancellationToken);
var workflowExecutionContext = new WorkflowExecutionContext(scope.ServiceProvider, workflowBlueprint, workflowInstance);
foreach (var activity in httpRequestActivities)
{
var activityExecutionContext = new ActivityExecutionContext(workflowExecutionContext, scope.ServiceProvider, activity);
yield return new ReceiveHttpRequestTrigger
{
ActivityId = activity.Id,
Path = (PathString)(await workflowBlueprint.ActivityPropertyProviders.GetProvider(activity.Id, nameof(ReceiveHttpRequest.Path))!.GetValueAsync(activityExecutionContext, cancellationToken))!,
Method = (string)(await workflowBlueprint.ActivityPropertyProviders.GetProvider(activity.Id, nameof(ReceiveHttpRequest.Method))!.GetValueAsync(activityExecutionContext, cancellationToken))!,
};
}
}
}
}

View file

@ -29,10 +29,10 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="MassTransit.AspNetCore" Version="7.0.3" />
<PackageReference Include="MassTransit.Extensions.DependencyInjection" Version="7.0.3" />
<PackageReference Include="MassTransit.Quartz" Version="7.0.3" />
<PackageReference Include="MassTransit.RabbitMQ" Version="7.0.3" />
<PackageReference Include="MassTransit.AspNetCore" Version="7.0.4" />
<PackageReference Include="MassTransit.Extensions.DependencyInjection" Version="7.0.4" />
<PackageReference Include="MassTransit.Quartz" Version="7.0.4" />
<PackageReference Include="MassTransit.RabbitMQ" Version="7.0.4" />
</ItemGroup>
<ItemGroup>

View file

@ -27,7 +27,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="MediatR" Version="8.1.0" />
<PackageReference Include="MediatR" Version="9.0.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="3.1.7" />
<PackageReference Include="Microsoft.Extensions.Localization.Abstractions" Version="3.1.7" />
<PackageReference Include="Microsoft.Extensions.Primitives" Version="3.1.7" />
@ -35,10 +35,10 @@
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="3.1.8" />
<PackageReference Include="Microsoft.Extensions.Localization.Abstractions" Version="3.1.8" />
<PackageReference Include="Microsoft.Extensions.Primitives" Version="3.1.8" />
<PackageReference Include="NodaTime" Version="3.0.0" />
<PackageReference Include="NodaTime" Version="3.0.2" />
<PackageReference Include="NodaTime.Serialization.JsonNet" Version="3.0.0" />
<PackageReference Include="Open.Linq.AsyncExtensions" Version="1.2.0" />
<PackageReference Include="Rebus" Version="6.3.1" />
<PackageReference Include="Rebus" Version="6.4.1" />
<PackageReference Include="System.ComponentModel.Annotations" Version="4.7.0" />
<PackageReference Include="System.Text.Json" Version="4.7.2" />
<PackageReference Include="System.Threading.Tasks.Extensions" Version="4.5.4" />

View file

@ -4,6 +4,7 @@ namespace Elsa.Models
{
public WorkflowExecutionScope()
{
Variables = new Variables();
}
public WorkflowExecutionScope(Variables variables)

View file

@ -17,7 +17,7 @@ namespace Elsa.Serialization.Handlers
{
var valueToken = token["Value"];
return valueToken == null ? null : ParseValue(valueToken);
return valueToken == null ? null! : ParseValue(valueToken);
}
public virtual void Serialize(JsonWriter writer, JsonSerializer serializer, Type type, JToken token, object? value)

View file

@ -1,7 +1,7 @@
using System.Threading;
using System.Threading.Tasks;
namespace Elsa.Runtime
namespace Elsa.Services
{
public interface IStartupRunner
{

View file

@ -1,7 +1,7 @@
using System.Threading;
using System.Threading.Tasks;
namespace Elsa.Runtime
namespace Elsa.Services
{
public interface IStartupTask
{

View file

@ -1,7 +1,10 @@
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Elsa.Models;
using Elsa.Services.Models;
using Elsa.Triggers;
namespace Elsa.Services
{

View file

@ -12,7 +12,6 @@ namespace Elsa.Services.Models
public class WorkflowExecutionContext
{
public WorkflowExecutionContext(
IExpressionEvaluator expressionEvaluator,
IServiceProvider serviceProvider,
IWorkflowBlueprint workflowBlueprint,
WorkflowInstance workflowInstance
@ -21,7 +20,6 @@ namespace Elsa.Services.Models
ServiceProvider = serviceProvider;
WorkflowBlueprint = workflowBlueprint;
WorkflowInstance = workflowInstance;
ExpressionEvaluator = expressionEvaluator;
ExecutionLog = new List<ExecutionLogEntry>(workflowInstance.ExecutionLog);
IsFirstPass = true;
}
@ -53,7 +51,6 @@ namespace Elsa.Services.Models
public void ScheduleActivity(ScheduledActivity activity) => WorkflowInstance.ScheduledActivities.Push(activity);
public ScheduledActivity PopScheduledActivity() => WorkflowInstance.ScheduledActivities.Pop();
public ScheduledActivity PeekScheduledActivity() => WorkflowInstance.ScheduledActivities.Peek();
public IExpressionEvaluator ExpressionEvaluator { get; }
public string? CorrelationId { get; set; }
public bool DeleteCompletedInstances { get; set; }
public ICollection<ExecutionLogEntry> ExecutionLog { get; }

View file

@ -0,0 +1,7 @@
namespace Elsa.Triggers
{
public interface ITrigger
{
string ActivityId { get; set; }
}
}

View file

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Elsa.Services.Models;
namespace Elsa.Triggers
{
public interface ITriggerProvider
{
Type ForType();
IAsyncEnumerable<ITrigger> GetTriggersAsync(IWorkflowBlueprint workflowBlueprint, CancellationToken cancellationToken = default);
}
}

View file

@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Threading;
using Elsa.Services.Models;
namespace Elsa.Triggers
{
public interface IWorkflowSelector
{
IAsyncEnumerable<WorkflowSelectorResult> SelectWorkflowsAsync(
Type triggerType,
Func<ITrigger, bool> evaluate,
CancellationToken cancellationToken = default);
}
}

View file

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Elsa.Services.Models;
namespace Elsa.Triggers
{
public abstract class TriggerProvider<T> : ITriggerProvider where T : ITrigger
{
public Type ForType() => typeof(T);
public abstract IAsyncEnumerable<ITrigger> GetTriggersAsync(IWorkflowBlueprint workflowBlueprint, CancellationToken cancellationToken = default);
}
}

View file

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Threading;
namespace Elsa.Triggers
{
public static class WorkflowSelectorExtensions
{
public static IAsyncEnumerable<WorkflowSelectorResult> SelectWorkflowsAsync<T>(
this IWorkflowSelector workflowSelector,
Func<T, bool> evaluate,
CancellationToken cancellationToken = default) where T : ITrigger =>
workflowSelector.SelectWorkflowsAsync(typeof(T), t => evaluate((T)t), cancellationToken);
}
}

View file

@ -0,0 +1,16 @@
using Elsa.Services.Models;
namespace Elsa.Triggers
{
public class WorkflowSelectorResult
{
public WorkflowSelectorResult(IWorkflowBlueprint workflowBlueprint, string activityId)
{
WorkflowBlueprint = workflowBlueprint;
ActivityId = activityId;
}
public IWorkflowBlueprint WorkflowBlueprint { get; }
public string ActivityId { get; }
}
}

View file

@ -1,6 +1,7 @@
using System.Threading;
using System.Threading.Tasks;
using Elsa.Runtime;
using Elsa.Services;
namespace Elsa.Data.Services
{

View file

@ -1,6 +1,7 @@
using System.Threading;
using System.Threading.Tasks;
using Elsa.Runtime;
using Elsa.Services;
using YesSql;
namespace Elsa.Data.Services

View file

@ -28,11 +28,12 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="AutoMapper" Version="10.0.0" />
<PackageReference Include="AutoMapper" Version="10.1.1" />
<PackageReference Include="Humanizer.Core" Version="2.8.26" />
<PackageReference Include="MediatR" Version="8.1.0" />
<PackageReference Include="MediatR.Extensions.Microsoft.DependencyInjection" Version="8.1.0" />
<PackageReference Include="MediatR" Version="9.0.0" />
<PackageReference Include="MediatR.Extensions.Microsoft.DependencyInjection" Version="9.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="2.2.0" />
<PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="1.1.1" />
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
<PackageReference Include="Microsoft.Extensions.Caching.Abstractions" Version="3.1.7" />
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="3.1.7" />
@ -55,6 +56,7 @@
<PackageReference Include="NodaTime.Serialization.JsonNet" Version="3.0.0" />
<PackageReference Include="Open.Linq.AsyncExtensions" Version="1.2.0" />
<PackageReference Include="Scrutor" Version="3.2.2" />
<PackageReference Include="System.Linq.Async" Version="4.1.1" />
<PackageReference Include="YamlDotNet" Version="8.1.2" />
<PackageReference Include="Rebus.ServiceProvider" Version="5.0.6" />
<PackageReference Include="YesSql.Provider.Sqlite" Version="1.0.0-beta-1547" />

View file

@ -21,6 +21,7 @@ using Elsa.Serialization;
using Elsa.Serialization.Formatters;
using Elsa.Services;
using Elsa.StartupTasks;
using Elsa.Triggers;
using Elsa.WorkflowProviders;
using MediatR;
using Microsoft.Extensions.DependencyInjection.Extensions;
@ -34,7 +35,7 @@ namespace Microsoft.Extensions.DependencyInjection
{
public static IServiceCollection AddElsaCore(
this IServiceCollection services,
Action<ElsaOptions> configure = default!)
Action<ElsaOptions>? configure = default)
{
var options = new ElsaOptions(services);
configure?.Invoke(options);
@ -102,6 +103,7 @@ namespace Microsoft.Extensions.DependencyInjection
.AddSingleton<IWorkflowSchedulerQueue, WorkflowSchedulerQueue>()
.AddScoped<IWorkflowHost, WorkflowHost>()
.AddSingleton<IWorkflowFactory, WorkflowFactory>()
.AddSingleton<IWorkflowSelector, WorkflowSelector>()
.AddScoped<IWorkflowDefinitionManager, WorkflowDefinitionManager>()
.AddScoped<IWorkflowInstanceManager, WorkflowInstanceManager>()
.AddIndexProvider<WorkflowDefinitionIndexProvider>()

View file

@ -1,3 +1,4 @@
using Elsa.Services;
using Microsoft.Extensions.DependencyInjection;
namespace Elsa.Runtime

View file

@ -1,6 +1,7 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using Elsa.Services;
using Microsoft.Extensions.DependencyInjection;
namespace Elsa.Runtime

View file

@ -1,5 +1,6 @@
using System.Threading;
using System.Threading.Tasks;
using Elsa.Services;
using Microsoft.Extensions.Hosting;
namespace Elsa.Runtime

View file

@ -1,5 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
using Elsa.ActivityResults;
@ -9,51 +11,41 @@ using Elsa.Expressions;
using Elsa.Messaging.Domain;
using Elsa.Models;
using Elsa.Services.Models;
using Elsa.Triggers;
using MediatR;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Open.Linq.AsyncExtensions;
namespace Elsa.Services
{
public class WorkflowHost : IWorkflowHost
{
private delegate ValueTask<IActivityExecutionResult> ActivityOperation(
ActivityExecutionContext activityExecutionContext,
IActivity activity,
CancellationToken cancellationToken);
private delegate ValueTask<IActivityExecutionResult> ActivityOperation(ActivityExecutionContext activityExecutionContext, IActivity activity, CancellationToken cancellationToken);
private static readonly ActivityOperation Execute = (context, activity, cancellationToken) =>
activity.ExecuteAsync(context, cancellationToken);
private static readonly ActivityOperation Execute = (context, activity, cancellationToken) => activity.ExecuteAsync(context, cancellationToken);
private static readonly ActivityOperation Resume = (context, activity, cancellationToken) => activity.ResumeAsync(context, cancellationToken);
private static readonly ActivityOperation Resume = (context, activity, cancellationToken) =>
activity.ResumeAsync(context, cancellationToken);
private readonly IWorkflowDefinitionManager _workflowDefinitionManager;
private readonly IWorkflowInstanceManager _workflowInstanceManager;
private readonly IWorkflowRegistry _workflowRegistry;
private readonly IWorkflowFactory _workflowFactory;
private readonly IExpressionEvaluator _expressionEvaluator;
private readonly IMediator _mediator;
private readonly IServiceProvider _serviceProvider;
private readonly IEnumerable<ITriggerProvider> _triggerProviders;
private readonly ILogger _logger;
public WorkflowHost(
IWorkflowDefinitionManager workflowDefinitionManager,
IWorkflowInstanceManager workflowInstanceManager,
IWorkflowRegistry workflowRegistry,
IWorkflowFactory workflowFactory,
IExpressionEvaluator expressionEvaluator,
IMediator mediator,
IServiceProvider serviceProvider,
IEnumerable<ITriggerProvider> triggerProviders,
ILogger<WorkflowHost> logger)
{
_workflowDefinitionManager = workflowDefinitionManager;
_workflowInstanceManager = workflowInstanceManager;
_workflowRegistry = workflowRegistry;
_workflowFactory = workflowFactory;
_expressionEvaluator = expressionEvaluator;
_mediator = mediator;
_serviceProvider = serviceProvider;
_triggerProviders = triggerProviders;
_logger = logger;
}
@ -72,7 +64,6 @@ namespace Elsa.Services
return await RunWorkflowAsync(workflowBlueprint, workflowInstance, activityId, input, cancellationToken);
}
public async ValueTask<WorkflowInstance> RunWorkflowAsync(
WorkflowInstance workflowInstance,
string? activityId = default,
@ -236,12 +227,11 @@ namespace Elsa.Services
workflowExecutionContext.Complete();
}
private WorkflowExecutionContext CreateWorkflowExecutionContext(
private static WorkflowExecutionContext CreateWorkflowExecutionContext(
IWorkflowBlueprint workflowBlueprint,
WorkflowInstance workflowInstance,
IServiceScope serviceScope) =>
new WorkflowExecutionContext(
_expressionEvaluator,
serviceScope.ServiceProvider,
workflowBlueprint,
workflowInstance);

View file

@ -3,6 +3,7 @@ using System.Threading.Tasks;
using Elsa.Messages;
using Elsa.Messaging.Distributed;
using Elsa.Runtime;
using Elsa.Services;
using Rebus.Bus;
namespace Elsa.StartupTasks

View file

@ -0,0 +1,43 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
using Elsa.Services;
using Elsa.Services.Models;
using Open.Linq.AsyncExtensions;
namespace Elsa.Triggers
{
public class WorkflowSelector : IWorkflowSelector
{
private readonly IWorkflowRegistry _workflowRegistry;
private readonly IEnumerable<ITriggerProvider> _triggerProviders;
public WorkflowSelector(IWorkflowRegistry workflowRegistry, IEnumerable<ITriggerProvider> triggerProviders)
{
_workflowRegistry = workflowRegistry;
_triggerProviders = triggerProviders;
}
public async IAsyncEnumerable<WorkflowSelectorResult> SelectWorkflowsAsync(
Type triggerType,
Func<ITrigger, bool> evaluate,
[EnumeratorCancellation] CancellationToken cancellationToken = default)
{
var providers = _triggerProviders.Where(x => x.ForType() == triggerType).ToList();
var workflowBlueprints = await _workflowRegistry.GetWorkflowsAsync(cancellationToken).ToList();
foreach (var provider in providers)
foreach (var workflowBlueprint in workflowBlueprints)
{
var triggers = provider.GetTriggersAsync(workflowBlueprint, cancellationToken);
await foreach (var trigger in triggers.WithCancellation(cancellationToken))
if (evaluate(trigger))
yield return new WorkflowSelectorResult(workflowBlueprint, trigger.ActivityId);
}
}
}
}

View file

@ -5,7 +5,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Azure.Storage.Blob" Version="11.1.7" />
<PackageReference Include="Microsoft.Azure.Storage.Blob" Version="11.2.2" />
</ItemGroup>
<ItemGroup>

View file

@ -6,7 +6,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting" Version="3.1.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="3.1.9" />
</ItemGroup>
<ItemGroup>

View file

@ -6,7 +6,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="3.1.8" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="3.1.9" />
</ItemGroup>
<ItemGroup>

View file

@ -6,7 +6,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting" Version="3.1.7" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="3.1.9" />
</ItemGroup>
<ItemGroup>

View file

@ -23,9 +23,9 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="HotChocolate.AspNetCore" Version="10.5.2" />
<PackageReference Include="HotChocolate.AspNetCore.Playground" Version="10.5.2" />
<PackageReference Include="HotChocolate.AspNetCore.Voyager" Version="10.5.2" />
<PackageReference Include="HotChocolate.AspNetCore" Version="10.5.3" />
<PackageReference Include="HotChocolate.AspNetCore.Playground" Version="10.5.3" />
<PackageReference Include="HotChocolate.AspNetCore.Voyager" Version="10.5.3" />
</ItemGroup>
<ItemGroup>

View file

@ -10,9 +10,9 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="GraphQL.Server.Ui.GraphiQL" Version="3.4.0" />
<PackageReference Include="GraphQL.Server.Ui.Playground" Version="3.4.0" />
<PackageReference Include="GraphQL.Server.Ui.Voyager" Version="3.4.0" />
<PackageReference Include="GraphQL.Server.Ui.GraphiQL" Version="4.0.1" />
<PackageReference Include="GraphQL.Server.Ui.Playground" Version="4.0.1" />
<PackageReference Include="GraphQL.Server.Ui.Voyager" Version="4.0.1" />
<PackageReference Include="YesSql.Provider.Sqlite" Version="1.0.0-beta-1547" />
</ItemGroup>

View file

@ -18,8 +18,8 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="AutoFixture" Version="4.13.0" />
<PackageReference Include="NodaTime" Version="3.0.0" />
<PackageReference Include="AutoFixture" Version="4.14.0" />
<PackageReference Include="NodaTime" Version="3.0.2" />
</ItemGroup>
<ItemGroup>

View file

@ -9,10 +9,10 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="AutoFixture.AutoMoq" Version="4.13.0" />
<PackageReference Include="AutoFixture.AutoMoq" Version="4.14.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.7.1" />
<PackageReference Include="Moq" Version="4.14.5" />
<PackageReference Include="NodaTime.Testing" Version="3.0.0" />
<PackageReference Include="Moq" Version="4.14.7" />
<PackageReference Include="NodaTime.Testing" Version="3.0.2" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
<PrivateAssets>all</PrivateAssets>