// Copyright (c) Nate McMaster.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Reflection;
using Microsoft.AspNetCore.Mvc.ApplicationParts;
using Microsoft.Extensions.DependencyInjection;
namespace BTCPayServer.Plugins.Dotnet
{
///
/// Extends the MVC builder.
///
public static class MvcPluginExtensions
{
///
/// Loads controllers and razor pages from a plugin assembly.
///
/// This creates a loader with set to true.
/// If you need more control over shared types, use instead.
///
///
/// The MVC builder
/// Full path the main .dll file for the plugin.
/// The builder
public static IMvcBuilder AddPluginFromAssemblyFile(this IMvcBuilder mvcBuilder, string assemblyFile)
{
var plugin = PluginLoader.CreateFromAssemblyFile(
assemblyFile, // create a plugin from for the .dll file
config =>
// this ensures that the version of MVC is shared between this app and the plugin
config.PreferSharedTypes = true);
return mvcBuilder.AddPluginLoader(plugin);
}
///
/// Loads controllers and razor pages from a plugin loader.
///
/// In order for this to work, the PluginLoader instance must be configured to share the types
/// and
/// (comes from Microsoft.AspNetCore.Mvc.Core.dll). The easiest way to ensure that is done correctly
/// is to set to true.
///
///
/// The MVC builder
/// An instance of PluginLoader.
/// The builder
public static IMvcBuilder AddPluginLoader(this IMvcBuilder mvcBuilder, PluginLoader pluginLoader)
{
var pluginAssembly = pluginLoader.LoadDefaultAssembly();
// This loads MVC application parts from plugin assemblies
var partFactory = ApplicationPartFactory.GetApplicationPartFactory(pluginAssembly);
foreach (var part in partFactory.GetApplicationParts(pluginAssembly))
{
mvcBuilder.PartManager.ApplicationParts.Add(part);
}
// This piece finds and loads related parts, such as MvcAppPlugin1.Views.dll.
var relatedAssembliesAttrs = pluginAssembly.GetCustomAttributes();
foreach (var attr in relatedAssembliesAttrs)
{
var assembly = pluginLoader.LoadAssembly(attr.AssemblyFileName);
partFactory = ApplicationPartFactory.GetApplicationPartFactory(assembly);
foreach (var part in partFactory.GetApplicationParts(assembly))
{
mvcBuilder.PartManager.ApplicationParts.Add(part);
}
}
return mvcBuilder;
}
}
}