Browse Source

Lazy references.

pull/637/head
Sebastian 5 years ago
parent
commit
84493107d2
  1. 36
      backend/src/Squidex.Domain.Apps.Entities/Assets/AssetsFluidExtension.cs
  2. 37
      backend/src/Squidex.Domain.Apps.Entities/Assets/AssetsJintExtension.cs
  3. 36
      backend/src/Squidex.Domain.Apps.Entities/Contents/ReferencesFluidExtension.cs
  4. 37
      backend/src/Squidex.Domain.Apps.Entities/Contents/ReferencesJintExtension.cs
  5. 9
      backend/tests/Squidex.Domain.Apps.Entities.Tests/Assets/AssetsFluidExtensionTests.cs
  6. 9
      backend/tests/Squidex.Domain.Apps.Entities.Tests/Assets/AssetsJintExtensionTests.cs
  7. 9
      backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/ReferencesFluidExtensionTests.cs
  8. 9
      backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/ReferencesJintExtensionTests.cs

36
backend/src/Squidex.Domain.Apps.Entities/Assets/AssetsFluidExtension.cs

@ -5,38 +5,40 @@
// All rights reserved. Licensed under the MIT license. // All rights reserved. Licensed under the MIT license.
// ========================================================================== // ==========================================================================
using System;
using System.IO; using System.IO;
using System.Text.Encodings.Web; using System.Text.Encodings.Web;
using System.Threading.Tasks; using System.Threading.Tasks;
using Fluid; using Fluid;
using Fluid.Ast; using Fluid.Ast;
using Fluid.Tags; using Fluid.Tags;
using GraphQL.Utilities;
using Squidex.Domain.Apps.Core.Rules.EnrichedEvents; using Squidex.Domain.Apps.Core.Rules.EnrichedEvents;
using Squidex.Domain.Apps.Core.Templates; using Squidex.Domain.Apps.Core.Templates;
using Squidex.Domain.Apps.Core.ValidateContent; using Squidex.Domain.Apps.Core.ValidateContent;
using Squidex.Domain.Apps.Entities.Apps;
using Squidex.Infrastructure; using Squidex.Infrastructure;
namespace Squidex.Domain.Apps.Entities.Assets namespace Squidex.Domain.Apps.Entities.Assets
{ {
public sealed class AssetsFluidExtension : IFluidExtension public sealed class AssetsFluidExtension : IFluidExtension
{ {
private readonly IAppProvider appProvider; private readonly IServiceProvider serviceProvider;
private readonly IAssetQueryService assetQuery;
private sealed class AssetTag : ArgumentsTag private sealed class AssetTag : ArgumentsTag
{ {
private readonly AssetsFluidExtension root; private readonly IServiceProvider serviceProvider;
public AssetTag(AssetsFluidExtension root) public AssetTag(IServiceProvider serviceProvider)
{ {
this.root = root; this.serviceProvider = serviceProvider;
} }
public override async ValueTask<Completion> WriteToAsync(TextWriter writer, TextEncoder encoder, TemplateContext context, FilterArgument[] arguments) public override async ValueTask<Completion> WriteToAsync(TextWriter writer, TextEncoder encoder, TemplateContext context, FilterArgument[] arguments)
{ {
if (arguments.Length == 2 && context.GetValue("event")?.ToObjectValue() is EnrichedEvent enrichedEvent) if (arguments.Length == 2 && context.GetValue("event")?.ToObjectValue() is EnrichedEvent enrichedEvent)
{ {
var app = await root.appProvider.GetAppAsync(enrichedEvent.AppId.Id, false); var app = await GetAppAsync(enrichedEvent);
if (app == null) if (app == null)
{ {
@ -49,7 +51,9 @@ namespace Squidex.Domain.Apps.Entities.Assets
var id = (await arguments[1].Expression.EvaluateAsync(context)).ToStringValue(); var id = (await arguments[1].Expression.EvaluateAsync(context)).ToStringValue();
var asset = await root.assetQuery.FindAsync(requestContext, DomainId.Create(id)); var assetQuery = serviceProvider.GetRequiredService<IAssetQueryService>();
var asset = await assetQuery.FindAsync(requestContext, DomainId.Create(id));
if (asset != null) if (asset != null)
{ {
@ -61,16 +65,20 @@ namespace Squidex.Domain.Apps.Entities.Assets
return Completion.Normal; return Completion.Normal;
} }
private Task<IAppEntity?> GetAppAsync(EnrichedEvent enrichedEvent)
{
var appProvider = serviceProvider.GetRequiredService<IAppProvider>();
return appProvider.GetAppAsync(enrichedEvent.AppId.Id, false);
}
} }
public AssetsFluidExtension(IAppProvider appProvider, IAssetQueryService assetQuery) public AssetsFluidExtension(IServiceProvider serviceProvider)
{ {
Guard.NotNull(assetQuery, nameof(assetQuery)); Guard.NotNull(serviceProvider, nameof(serviceProvider));
Guard.NotNull(appProvider, nameof(appProvider));
this.assetQuery = assetQuery;
this.appProvider = appProvider; this.serviceProvider = serviceProvider;
} }
public void RegisterGlobalTypes(IMemberAccessStrategy memberAccessStrategy) public void RegisterGlobalTypes(IMemberAccessStrategy memberAccessStrategy)
@ -86,7 +94,7 @@ namespace Squidex.Domain.Apps.Entities.Assets
public void RegisterLanguageExtensions(FluidParserFactory factory) public void RegisterLanguageExtensions(FluidParserFactory factory)
{ {
factory.RegisterTag("asset", new AssetTag(this)); factory.RegisterTag("asset", new AssetTag(serviceProvider));
} }
} }
} }

37
backend/src/Squidex.Domain.Apps.Entities/Assets/AssetsJintExtension.cs

@ -10,9 +10,11 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Security.Claims; using System.Security.Claims;
using System.Threading.Tasks; using System.Threading.Tasks;
using GraphQL.Utilities;
using Jint.Native; using Jint.Native;
using Jint.Runtime; using Jint.Runtime;
using Squidex.Domain.Apps.Core.Scripting; using Squidex.Domain.Apps.Core.Scripting;
using Squidex.Domain.Apps.Entities.Apps;
using Squidex.Infrastructure; using Squidex.Infrastructure;
using Squidex.Infrastructure.Tasks; using Squidex.Infrastructure.Tasks;
@ -21,17 +23,13 @@ namespace Squidex.Domain.Apps.Entities.Assets
public sealed class AssetsJintExtension : IJintExtension public sealed class AssetsJintExtension : IJintExtension
{ {
private delegate void GetAssetsDelegate(JsValue references, Action<JsValue> callback); private delegate void GetAssetsDelegate(JsValue references, Action<JsValue> callback);
private readonly IAppProvider appProvider; private readonly IServiceProvider serviceProvider;
private readonly IAssetQueryService assetQuery;
public AssetsJintExtension(IAppProvider appProvider, IAssetQueryService assetQuery) public AssetsJintExtension(IServiceProvider serviceProvider)
{ {
Guard.NotNull(appProvider, nameof(appProvider)); Guard.NotNull(serviceProvider, nameof(serviceProvider));
Guard.NotNull(assetQuery, nameof(assetQuery));
this.appProvider = appProvider; this.serviceProvider = serviceProvider;
this.assetQuery = assetQuery;
} }
public void ExtendAsync(ExecutionContext context) public void ExtendAsync(ExecutionContext context)
@ -90,17 +88,14 @@ namespace Squidex.Domain.Apps.Entities.Assets
try try
{ {
var app = await appProvider.GetAppAsync(appId); var app = await GetAppAsync(appId);
if (app == null)
{
throw new JavaScriptException("App does not exist.");
}
var requestContext = var requestContext =
new Context(user, app).Clone(b => b new Context(user, app).Clone(b => b
.WithoutTotal()); .WithoutTotal());
var assetQuery = serviceProvider.GetRequiredService<IAssetQueryService>();
var assets = await assetQuery.QueryAsync(requestContext, null, Q.Empty.WithIds(ids)); var assets = await assetQuery.QueryAsync(requestContext, null, Q.Empty.WithIds(ids));
callback(JsValue.FromObject(context.Engine, assets.ToArray())); callback(JsValue.FromObject(context.Engine, assets.ToArray()));
@ -110,5 +105,19 @@ namespace Squidex.Domain.Apps.Entities.Assets
context.Fail(ex); context.Fail(ex);
} }
} }
private async Task<IAppEntity> GetAppAsync(DomainId appId)
{
var appProvider = serviceProvider.GetRequiredService<IAppProvider>();
var app = await appProvider.GetAppAsync(appId);
if (app == null)
{
throw new JavaScriptException("App does not exist.");
}
return app;
}
} }
} }

36
backend/src/Squidex.Domain.Apps.Entities/Contents/ReferencesFluidExtension.cs

@ -5,6 +5,7 @@
// All rights reserved. Licensed under the MIT license. // All rights reserved. Licensed under the MIT license.
// ========================================================================== // ==========================================================================
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
@ -13,8 +14,10 @@ using System.Threading.Tasks;
using Fluid; using Fluid;
using Fluid.Ast; using Fluid.Ast;
using Fluid.Tags; using Fluid.Tags;
using GraphQL.Utilities;
using Squidex.Domain.Apps.Core.Rules.EnrichedEvents; using Squidex.Domain.Apps.Core.Rules.EnrichedEvents;
using Squidex.Domain.Apps.Core.Templates; using Squidex.Domain.Apps.Core.Templates;
using Squidex.Domain.Apps.Entities.Apps;
using Squidex.Infrastructure; using Squidex.Infrastructure;
#pragma warning disable CA1826 // Do not use Enumerable methods on indexable collections #pragma warning disable CA1826 // Do not use Enumerable methods on indexable collections
@ -23,23 +26,22 @@ namespace Squidex.Domain.Apps.Entities.Contents
{ {
public sealed class ReferencesFluidExtension : IFluidExtension public sealed class ReferencesFluidExtension : IFluidExtension
{ {
private readonly IAppProvider appProvider; private readonly IServiceProvider serviceProvider;
private readonly IContentQueryService contentQuery;
private sealed class ReferenceTag : ArgumentsTag private sealed class ReferenceTag : ArgumentsTag
{ {
private readonly ReferencesFluidExtension root; private readonly IServiceProvider serviceProvider;
public ReferenceTag(ReferencesFluidExtension root) public ReferenceTag(IServiceProvider serviceProvider)
{ {
this.root = root; this.serviceProvider = serviceProvider;
} }
public override async ValueTask<Completion> WriteToAsync(TextWriter writer, TextEncoder encoder, TemplateContext context, FilterArgument[] arguments) public override async ValueTask<Completion> WriteToAsync(TextWriter writer, TextEncoder encoder, TemplateContext context, FilterArgument[] arguments)
{ {
if (arguments.Length == 2 && context.GetValue("event")?.ToObjectValue() is EnrichedEvent enrichedEvent) if (arguments.Length == 2 && context.GetValue("event")?.ToObjectValue() is EnrichedEvent enrichedEvent)
{ {
var app = await root.appProvider.GetAppAsync(enrichedEvent.AppId.Id, false); var app = await GetAppAsync(enrichedEvent);
if (app == null) if (app == null)
{ {
@ -57,7 +59,9 @@ namespace Squidex.Domain.Apps.Entities.Contents
var domainId = DomainId.Create(id); var domainId = DomainId.Create(id);
var domainIds = new List<DomainId> { domainId }; var domainIds = new List<DomainId> { domainId };
var contents = await root.contentQuery.QueryAsync(requestContext, Q.Empty.WithIds(domainIds)); var contentQuery = serviceProvider.GetRequiredService<IContentQueryService>();
var contents = await contentQuery.QueryAsync(requestContext, Q.Empty.WithIds(domainIds));
var content = contents.FirstOrDefault(); var content = contents.FirstOrDefault();
if (content != null) if (content != null)
@ -70,16 +74,20 @@ namespace Squidex.Domain.Apps.Entities.Contents
return Completion.Normal; return Completion.Normal;
} }
private Task<IAppEntity?> GetAppAsync(EnrichedEvent enrichedEvent)
{
var appProvider = serviceProvider.GetRequiredService<IAppProvider>();
return appProvider.GetAppAsync(enrichedEvent.AppId.Id, false);
}
} }
public ReferencesFluidExtension(IAppProvider appProvider, IContentQueryService contentQuery) public ReferencesFluidExtension(IServiceProvider serviceProvider)
{ {
Guard.NotNull(contentQuery, nameof(contentQuery)); Guard.NotNull(serviceProvider, nameof(serviceProvider));
Guard.NotNull(appProvider, nameof(appProvider));
this.contentQuery = contentQuery;
this.appProvider = appProvider; this.serviceProvider = serviceProvider;
} }
public void RegisterGlobalTypes(IMemberAccessStrategy memberAccessStrategy) public void RegisterGlobalTypes(IMemberAccessStrategy memberAccessStrategy)
@ -94,7 +102,7 @@ namespace Squidex.Domain.Apps.Entities.Contents
public void RegisterLanguageExtensions(FluidParserFactory factory) public void RegisterLanguageExtensions(FluidParserFactory factory)
{ {
factory.RegisterTag("reference", new ReferenceTag(this)); factory.RegisterTag("reference", new ReferenceTag(serviceProvider));
} }
} }
} }

37
backend/src/Squidex.Domain.Apps.Entities/Contents/ReferencesJintExtension.cs

@ -12,7 +12,9 @@ using System.Security.Claims;
using System.Threading.Tasks; using System.Threading.Tasks;
using Jint.Native; using Jint.Native;
using Jint.Runtime; using Jint.Runtime;
using Microsoft.Extensions.DependencyInjection;
using Squidex.Domain.Apps.Core.Scripting; using Squidex.Domain.Apps.Core.Scripting;
using Squidex.Domain.Apps.Entities.Apps;
using Squidex.Infrastructure; using Squidex.Infrastructure;
using Squidex.Infrastructure.Tasks; using Squidex.Infrastructure.Tasks;
@ -21,17 +23,13 @@ namespace Squidex.Domain.Apps.Entities.Contents
public sealed class ReferencesJintExtension : IJintExtension public sealed class ReferencesJintExtension : IJintExtension
{ {
private delegate void GetReferencesDelegate(JsValue references, Action<JsValue> callback); private delegate void GetReferencesDelegate(JsValue references, Action<JsValue> callback);
private readonly IAppProvider appProvider; private readonly IServiceProvider serviceProvider;
private readonly IContentQueryService contentQuery;
public ReferencesJintExtension(IAppProvider appProvider, IContentQueryService contentQuery) public ReferencesJintExtension(IServiceProvider serviceProvider)
{ {
Guard.NotNull(appProvider, nameof(appProvider)); Guard.NotNull(serviceProvider, nameof(serviceProvider));
Guard.NotNull(contentQuery, nameof(contentQuery));
this.appProvider = appProvider; this.serviceProvider = serviceProvider;
this.contentQuery = contentQuery;
} }
public void ExtendAsync(ExecutionContext context) public void ExtendAsync(ExecutionContext context)
@ -90,12 +88,7 @@ namespace Squidex.Domain.Apps.Entities.Contents
try try
{ {
var app = await appProvider.GetAppAsync(appId); var app = await GetAppAsync(appId);
if (app == null)
{
throw new JavaScriptException("App does not exist.");
}
var requestContext = var requestContext =
new Context(user, app).Clone(b => b new Context(user, app).Clone(b => b
@ -103,6 +96,8 @@ namespace Squidex.Domain.Apps.Entities.Contents
.WithUnpublished() .WithUnpublished()
.WithoutTotal()); .WithoutTotal());
var contentQuery = serviceProvider.GetRequiredService<IContentQueryService>();
var contents = await contentQuery.QueryAsync(requestContext, Q.Empty.WithIds(ids)); var contents = await contentQuery.QueryAsync(requestContext, Q.Empty.WithIds(ids));
callback(JsValue.FromObject(context.Engine, contents.ToArray())); callback(JsValue.FromObject(context.Engine, contents.ToArray()));
@ -112,5 +107,19 @@ namespace Squidex.Domain.Apps.Entities.Contents
context.Fail(ex); context.Fail(ex);
} }
} }
private async Task<IAppEntity> GetAppAsync(DomainId appId)
{
var appProvider = serviceProvider.GetRequiredService<IAppProvider>();
var app = await appProvider.GetAppAsync(appId);
if (app == null)
{
throw new JavaScriptException("App does not exist.");
}
return app;
}
} }
} }

9
backend/tests/Squidex.Domain.Apps.Entities.Tests/Assets/AssetsFluidExtensionTests.cs

@ -7,6 +7,7 @@
using System.Threading.Tasks; using System.Threading.Tasks;
using FakeItEasy; using FakeItEasy;
using Microsoft.Extensions.DependencyInjection;
using Squidex.Domain.Apps.Core.Contents; using Squidex.Domain.Apps.Core.Contents;
using Squidex.Domain.Apps.Core.Rules.EnrichedEvents; using Squidex.Domain.Apps.Core.Rules.EnrichedEvents;
using Squidex.Domain.Apps.Core.Templates; using Squidex.Domain.Apps.Core.Templates;
@ -26,9 +27,15 @@ namespace Squidex.Domain.Apps.Entities.Assets
public AssetsFluidExtensionTests() public AssetsFluidExtensionTests()
{ {
var services =
new ServiceCollection()
.AddSingleton(appProvider)
.AddSingleton(assetQuery)
.BuildServiceProvider();
var extensions = new IFluidExtension[] var extensions = new IFluidExtension[]
{ {
new AssetsFluidExtension(appProvider, assetQuery) new AssetsFluidExtension(services)
}; };
A.CallTo(() => appProvider.GetAppAsync(appId.Id, false)) A.CallTo(() => appProvider.GetAppAsync(appId.Id, false))

9
backend/tests/Squidex.Domain.Apps.Entities.Tests/Assets/AssetsJintExtensionTests.cs

@ -9,6 +9,7 @@ using System.Security.Claims;
using System.Threading.Tasks; using System.Threading.Tasks;
using FakeItEasy; using FakeItEasy;
using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Squidex.Domain.Apps.Core.Contents; using Squidex.Domain.Apps.Core.Contents;
using Squidex.Domain.Apps.Core.Scripting; using Squidex.Domain.Apps.Core.Scripting;
@ -29,9 +30,15 @@ namespace Squidex.Domain.Apps.Entities.Assets
public AssetsJintExtensionTests() public AssetsJintExtensionTests()
{ {
var services =
new ServiceCollection()
.AddSingleton(appProvider)
.AddSingleton(assetQuery)
.BuildServiceProvider();
var extensions = new IJintExtension[] var extensions = new IJintExtension[]
{ {
new AssetsJintExtension(appProvider, assetQuery) new AssetsJintExtension(services)
}; };
A.CallTo(() => appProvider.GetAppAsync(appId.Id, false)) A.CallTo(() => appProvider.GetAppAsync(appId.Id, false))

9
backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/ReferencesFluidExtensionTests.cs

@ -7,6 +7,7 @@
using System.Threading.Tasks; using System.Threading.Tasks;
using FakeItEasy; using FakeItEasy;
using Microsoft.Extensions.DependencyInjection;
using Squidex.Domain.Apps.Core.Contents; using Squidex.Domain.Apps.Core.Contents;
using Squidex.Domain.Apps.Core.Rules.EnrichedEvents; using Squidex.Domain.Apps.Core.Rules.EnrichedEvents;
using Squidex.Domain.Apps.Core.Templates; using Squidex.Domain.Apps.Core.Templates;
@ -26,9 +27,15 @@ namespace Squidex.Domain.Apps.Entities.Contents
public ReferencesFluidExtensionTests() public ReferencesFluidExtensionTests()
{ {
var services =
new ServiceCollection()
.AddSingleton(appProvider)
.AddSingleton(contentQuery)
.BuildServiceProvider();
var extensions = new IFluidExtension[] var extensions = new IFluidExtension[]
{ {
new ReferencesFluidExtension(appProvider, contentQuery) new ReferencesFluidExtension(services)
}; };
A.CallTo(() => appProvider.GetAppAsync(appId.Id, false)) A.CallTo(() => appProvider.GetAppAsync(appId.Id, false))

9
backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/ReferencesJintExtensionTests.cs

@ -9,6 +9,7 @@ using System.Security.Claims;
using System.Threading.Tasks; using System.Threading.Tasks;
using FakeItEasy; using FakeItEasy;
using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Squidex.Domain.Apps.Core.Contents; using Squidex.Domain.Apps.Core.Contents;
using Squidex.Domain.Apps.Core.Scripting; using Squidex.Domain.Apps.Core.Scripting;
@ -29,9 +30,15 @@ namespace Squidex.Domain.Apps.Entities.Contents
public ReferencesJintExtensionTests() public ReferencesJintExtensionTests()
{ {
var services =
new ServiceCollection()
.AddSingleton(appProvider)
.AddSingleton(contentQuery)
.BuildServiceProvider();
var extensions = new IJintExtension[] var extensions = new IJintExtension[]
{ {
new ReferencesJintExtension(appProvider, contentQuery) new ReferencesJintExtension(services)
}; };
A.CallTo(() => appProvider.GetAppAsync(appId.Id, false)) A.CallTo(() => appProvider.GetAppAsync(appId.Id, false))

Loading…
Cancel
Save