Browse Source

Fix controller loading in plugins with sample.

pull/352/head
Sebastian Stehle 7 years ago
parent
commit
aca8bf2707
  1. 2
      extensions/Squidex.Extensions/Samples/AssetStore/MemoryAssetStorePlugin.cs
  2. 27
      extensions/Squidex.Extensions/Samples/Controllers/PluginController.cs
  3. 1
      extensions/Squidex.Extensions/Squidex.Extensions.csproj
  4. 2
      src/Squidex.Infrastructure.MongoDb/MongoDb/MongoExtensions.cs
  5. 50
      src/Squidex/Pipeline/Plugins/MvcParts.cs
  6. 86
      src/Squidex/Pipeline/Plugins/PluginExtensions.cs
  7. 73
      src/Squidex/Pipeline/Plugins/PluginLoaders.cs

2
extensions/Squidex.Extensions/Samples/MemoryAssetStorePlugin.cs → extensions/Squidex.Extensions/Samples/AssetStore/MemoryAssetStorePlugin.cs

@ -11,7 +11,7 @@ using Microsoft.Extensions.DependencyInjection;
using Squidex.Infrastructure.Assets;
using Squidex.Infrastructure.Plugins;
namespace Squidex.Extensions.Samples
namespace Squidex.Extensions.Samples.AssetStore
{
public sealed class MemoryAssetStorePlugin : IPlugin
{

27
extensions/Squidex.Extensions/Samples/Controllers/PluginController.cs

@ -0,0 +1,27 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using Microsoft.AspNetCore.Mvc;
using Squidex.Infrastructure.Commands;
using Squidex.Web;
namespace Squidex.Extensions.Samples.Controllers
{
public sealed class PluginController : ApiController
{
public PluginController(ICommandBus commandBus)
: base(commandBus)
{
}
[Route("/plugins/sample")]
public IActionResult Test()
{
return Ok(new { text = "I am Plugin" });
}
}
}

1
extensions/Squidex.Extensions/Squidex.Extensions.csproj

@ -5,6 +5,7 @@
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Squidex.Domain.Apps.Core.Operations\Squidex.Domain.Apps.Core.Operations.csproj" />
<ProjectReference Include="..\..\src\Squidex.Web\Squidex.Web.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Algolia.Search" Version="5.3.1" />

2
src/Squidex.Infrastructure.MongoDb/MongoDb/MongoExtensions.cs

@ -133,7 +133,7 @@ namespace Squidex.Infrastructure.MongoDb
}
}
public static async Task UpsertVersionedAsync<T, TKey>(this IMongoCollection<T> collection, TKey key, long oldVersion, long newVersion, T doc) where T : IVersionedEntity<TKey>
public static async Task UpsertVersionedAsync<T, TKey>(this IMongoCollection<T> collection, TKey key, long oldVersion, T doc) where T : IVersionedEntity<TKey>
{
try
{

50
src/Squidex/Pipeline/Plugins/MvcParts.cs

@ -0,0 +1,50 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Microsoft.AspNetCore.Mvc.ApplicationParts;
using Microsoft.Extensions.DependencyInjection;
namespace Squidex.Pipeline.Plugins
{
public static class MvcParts
{
public static void AddParts(this Assembly assembly, IMvcBuilder mvcBuilder)
{
mvcBuilder.ConfigureApplicationPartManager(manager =>
{
var parts = manager.ApplicationParts;
AddParts(parts, assembly);
foreach (var reference in RelatedAssemblyAttribute.GetRelatedAssemblies(assembly, false))
{
AddParts(parts, assembly);
}
});
}
private static void AddParts(IList<ApplicationPart> applicationParts, Assembly assembly)
{
var partFactory = ApplicationPartFactory.GetApplicationPartFactory(assembly);
foreach (var part in partFactory.GetApplicationParts(assembly))
{
var existings = applicationParts.Where(x => x.Name == part.Name).ToList();
foreach (var existing in existings)
{
applicationParts.Remove(existing);
}
applicationParts.Add(part);
}
}
}
}

86
src/Squidex/Pipeline/Plugins/PluginExtensions.cs

@ -6,37 +6,17 @@
// ==========================================================================
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using McMaster.NETCore.Plugins;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Mvc.ApplicationParts;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Squidex.Domain.Apps.Core;
using Squidex.Domain.Apps.Entities;
using Squidex.Domain.Apps.Events;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Log;
using Squidex.Infrastructure.Plugins;
using Squidex.Web;
namespace Squidex.Pipeline.Plugins
{
public static class PluginExtensions
{
private static readonly Type[] SharedTypes =
{
typeof(IPlugin),
typeof(SquidexCoreModel),
typeof(SquidexCoreOperations),
typeof(SquidexEntities),
typeof(SquidexEvents),
typeof(SquidexInfrastructure),
typeof(SquidexWeb)
};
public static IMvcBuilder AddMyPlugins(this IMvcBuilder mvcBuilder, IConfiguration config)
{
var pluginManager = new PluginManager();
@ -47,7 +27,7 @@ namespace Squidex.Pipeline.Plugins
{
foreach (var path in options.Plugins)
{
var plugin = LoadPlugin(path);
var plugin = PluginLoaders.LoadPlugin(path);
if (plugin != null)
{
@ -55,13 +35,7 @@ namespace Squidex.Pipeline.Plugins
{
var pluginAssembly = plugin.LoadDefaultAssembly();
AddParts(mvcBuilder, pluginAssembly);
foreach (var relatedAssembly in RelatedAssemblyAttribute.GetRelatedAssemblies(pluginAssembly, false))
{
AddParts(mvcBuilder, relatedAssembly);
}
pluginAssembly.AddParts(mvcBuilder);
pluginManager.Add(path, pluginAssembly);
}
catch (Exception ex)
@ -83,66 +57,12 @@ namespace Squidex.Pipeline.Plugins
return mvcBuilder;
}
private static PluginLoader LoadPlugin(string pluginPath)
{
foreach (var candidate in GetPaths(pluginPath))
{
if (candidate.Extension.Equals(".dll", StringComparison.OrdinalIgnoreCase))
{
return PluginLoader.CreateFromAssemblyFile(candidate.FullName, PluginLoaderOptions.PreferSharedTypes);
}
if (candidate.Extension.Equals(".json", StringComparison.OrdinalIgnoreCase))
{
return PluginLoader.CreateFromConfigFile(candidate.FullName, SharedTypes);
}
}
return null;
}
private static IEnumerable<FileInfo> GetPaths(string pluginPath)
{
var candidate = new FileInfo(Path.GetFullPath(pluginPath));
if (candidate.Exists)
{
yield return candidate;
}
if (!Path.IsPathRooted(pluginPath))
{
candidate = new FileInfo(Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), pluginPath));
if (candidate.Exists)
{
yield return candidate;
}
}
}
public static void UsePlugins(this IApplicationBuilder app)
{
var pluginManager = app.ApplicationServices.GetRequiredService<PluginManager>();
pluginManager.Configure(app);
var log = app.ApplicationServices.GetService<ISemanticLog>();
if (log != null)
{
pluginManager.Log(log);
}
}
private static void AddParts(IMvcBuilder mvcBuilder, Assembly assembly)
{
var partFactory = ApplicationPartFactory.GetApplicationPartFactory(assembly);
foreach (var part in partFactory.GetApplicationParts(assembly))
{
mvcBuilder.PartManager.ApplicationParts.Add(part);
}
pluginManager.Log(app.ApplicationServices.GetService<ISemanticLog>());
}
}
}

73
src/Squidex/Pipeline/Plugins/PluginLoaders.cs

@ -0,0 +1,73 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using McMaster.NETCore.Plugins;
using Squidex.Domain.Apps.Core;
using Squidex.Domain.Apps.Entities;
using Squidex.Domain.Apps.Events;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Plugins;
using Squidex.Web;
namespace Squidex.Pipeline.Plugins
{
public static class PluginLoaders
{
private static readonly Type[] SharedTypes =
{
typeof(IPlugin),
typeof(SquidexCoreModel),
typeof(SquidexCoreOperations),
typeof(SquidexEntities),
typeof(SquidexEvents),
typeof(SquidexInfrastructure),
typeof(SquidexWeb)
};
public static PluginLoader LoadPlugin(string pluginPath)
{
foreach (var candidate in GetPaths(pluginPath))
{
if (candidate.Extension.Equals(".dll", StringComparison.OrdinalIgnoreCase))
{
return PluginLoader.CreateFromAssemblyFile(candidate.FullName, PluginLoaderOptions.PreferSharedTypes);
}
if (candidate.Extension.Equals(".json", StringComparison.OrdinalIgnoreCase))
{
return PluginLoader.CreateFromConfigFile(candidate.FullName, SharedTypes);
}
}
return null;
}
private static IEnumerable<FileInfo> GetPaths(string pluginPath)
{
var candidate = new FileInfo(Path.GetFullPath(pluginPath));
if (candidate.Exists)
{
yield return candidate;
}
if (!Path.IsPathRooted(pluginPath))
{
candidate = new FileInfo(Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), pluginPath));
if (candidate.Exists)
{
yield return candidate;
}
}
}
}
}
Loading…
Cancel
Save