diff --git a/.idea/.idea.PSCHelpdesk/.idea/.name b/.idea/.idea.PSCHelpdesk/.idea/.name new file mode 100644 index 0000000..6f7d947 --- /dev/null +++ b/.idea/.idea.PSCHelpdesk/.idea/.name @@ -0,0 +1 @@ +PSCHelpdesk \ No newline at end of file diff --git a/.idea/.idea.PSCHelpdesk/.idea/workspace.xml b/.idea/.idea.PSCHelpdesk/.idea/workspace.xml index c7a52dc..925d175 100644 --- a/.idea/.idea.PSCHelpdesk/.idea/workspace.xml +++ b/.idea/.idea.PSCHelpdesk/.idea/workspace.xml @@ -11,52 +11,18 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + - - - - - - - - - - - + + + + + + + + + + + + - - - - - - - - - - - - - + + - - - - - - - - - - - - - - - - + + + + + + { "customColor": "", "associatedIndex": 8 @@ -227,6 +174,7 @@ + @@ -242,56 +190,43 @@ file://$PROJECT_DIR$/PSCHelpdesk/PSCHelpdesk/ViewModels/MainWindowViewModel.cs - 86 + 78 - - file://$PROJECT_DIR$/PSCHelpdesk/PSCHelpdesk/ViewModels/MainWindowViewModel.cs - 83 + 75 - - file://$PROJECT_DIR$/PSCHelpdesk/PSCHelpdesk/ViewModels/MainWindowViewModel.cs - 84 + 76 - - - - file://$PROJECT_DIR$/PSCHelpdesk/PSCHelpdesk/Views/ContentDisplay.axaml.cs - 71 - - - - - - - file://$PROJECT_DIR$/PSCHelpdesk/PSCHelpdesk/Views/ContentDisplay.axaml.cs 37 @@ -306,17 +241,56 @@ - file://$PROJECT_DIR$/PSCHelpdesk/PSCHelpdesk/ViewModels/MainWindowViewModel.cs - 48 - + file://$PROJECT_DIR$/HetznerServer/Menu/MainMenu.cs + 13 + - - - + + file://$PROJECT_DIR$/HetznerServer/HetznerServer.cs + 26 + + + + + + + + + file://$PROJECT_DIR$/HetznerServer/HetznerServer.cs + 28 + + + + + + + + + file://$PROJECT_DIR$/HetznerServer/HetznerServer.cs + 27 + + + + + + + diff --git a/HetznerServer/HetznerServer.cs b/HetznerServer/HetznerServer.cs index 5ede775..7d67244 100644 --- a/HetznerServer/HetznerServer.cs +++ b/HetznerServer/HetznerServer.cs @@ -1,8 +1,11 @@ +using CommunityToolkit.Mvvm.DependencyInjection; using Prise.Plugin; +using PSCHelpdesk.Plugins.HetznerServer.Menu; using PSCHelpdesk.Plugins.HetznerServer.ViewModels; using PSCHelpdesk.Plugins.HetznerServer.Views; using PSCHelpdesk.Shared.Menu; using PSCHelpdesk.Shared.Plugin; +using PSCHelpdesk.Shared.Service; namespace PSCHelpdesk.Plugins.HetznerServer; @@ -16,11 +19,18 @@ public class HetznerServer : Contract public async Task> addMenu() { - var list = new List(); + var menu = new MainMenu(); + //menu.addMenu(); + + + + var menuService = Ioc.Default.GetService(); + var testService = Ioc.Default.GetService(); + var list = new List(); var serverTab = new Item() { Header = "Server", - CommandParameter = typeof(ServerViewModel), + // CommandParameter = typeof(ServerViewModel) }; list.Add(serverTab); return list; diff --git a/HetznerServer/HetznerServer.csproj b/HetznerServer/HetznerServer.csproj index 6180a2f..6035396 100644 --- a/HetznerServer/HetznerServer.csproj +++ b/HetznerServer/HetznerServer.csproj @@ -20,6 +20,9 @@ + + + @@ -40,7 +43,6 @@ - diff --git a/HetznerServer/HetznerServerBootstrap.cs b/HetznerServer/HetznerServerBootstrap.cs index 85eba2c..e6b1136 100644 --- a/HetznerServer/HetznerServerBootstrap.cs +++ b/HetznerServer/HetznerServerBootstrap.cs @@ -1,4 +1,5 @@ using PSCHelpdesk.Plugins.HetznerServer.ViewModels; +using PSCHelpdesk.Shared.Service; namespace PSCHelpdesk.Plugins.HetznerServer; @@ -9,8 +10,12 @@ using Prise.Plugin; [PluginBootstrapper(PluginType = typeof(HetznerServer))] public class HetznerServerBootstrap : IPluginBootstrapper { + //[BootstrapperService(ServiceType = typeof(IMenuService), ProxyType = typeof(MenuService))] + //private readonly IMenuService menuService; + public IServiceCollection Bootstrap(IServiceCollection services) { + //services.AddSingleton(this.menuService); services.AddTransient(); return services; } diff --git a/HetznerServer/Menu/MainMenu.cs b/HetznerServer/Menu/MainMenu.cs new file mode 100644 index 0000000..86b0685 --- /dev/null +++ b/HetznerServer/Menu/MainMenu.cs @@ -0,0 +1,20 @@ +using Prise.Plugin; +using PSCHelpdesk.Shared.Menu; +using PSCHelpdesk.Shared.Service; + +namespace PSCHelpdesk.Plugins.HetznerServer.Menu; + +public class MainMenu +{ + [PluginService(ProvidedBy = ProvidedBy.Host, ServiceType = typeof(IMenuService))] + private readonly IMenuService menuService; + + public void addMenu() + { + this.menuService.AddMenuItem(new Item() + { + Header = "Hetzner", + }); + } + +} \ No newline at end of file diff --git a/HetznerServer/MenuService.cs b/HetznerServer/MenuService.cs new file mode 100644 index 0000000..fb2c29e --- /dev/null +++ b/HetznerServer/MenuService.cs @@ -0,0 +1,15 @@ +using Prise.Proxy; +using PSCHelpdesk.Shared.Menu; +using PSCHelpdesk.Shared.Service; + +namespace PSCHelpdesk.Plugins.HetznerServer; + +public class MenuService : ReverseProxy, IMenuService +{ + public MenuService(object hostService) : base(hostService) { } + + public void AddMenuItem(Item item) + { + this.InvokeOnHostService(new[] { item }); + } +} \ No newline at end of file diff --git a/PSCHelpdesk.sln b/PSCHelpdesk.sln index f06fecb..c15c3bc 100644 --- a/PSCHelpdesk.sln +++ b/PSCHelpdesk.sln @@ -18,6 +18,16 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HetznerServer", "HetznerSer EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Nextcloud", "Nextcloud\Nextcloud.csproj", "{4C34E3F4-718D-4E15-97A2-AE61A4ACEE02}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Vendor", "Vendor", "{D45462B2-C09A-4BC6-A8B1-F03C6533B084}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Prise", "Vendor\Prise\Prise.csproj", "{AD222F87-EAC5-4120-AA33-EB32DF2DDCD5}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Prise.Plugin", "Vendor\Prise.Plugin\Prise.Plugin.csproj", "{F4EF7157-C5F0-4444-9E49-28F6BD56295F}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Prise.ReverseProxy", "Vendor\Prise.ReverseProxy\Prise.ReverseProxy.csproj", "{52EFDD1B-B775-49A1-BD3D-E7B7F6A989EA}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Prise.Proxy", "Vendor\Prise.Proxy\Prise.Proxy.csproj", "{79029F78-5113-46E4-8896-436707A7251F}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -60,9 +70,29 @@ Global {4C34E3F4-718D-4E15-97A2-AE61A4ACEE02}.Debug|Any CPU.Build.0 = Debug|Any CPU {4C34E3F4-718D-4E15-97A2-AE61A4ACEE02}.Release|Any CPU.ActiveCfg = Release|Any CPU {4C34E3F4-718D-4E15-97A2-AE61A4ACEE02}.Release|Any CPU.Build.0 = Release|Any CPU + {AD222F87-EAC5-4120-AA33-EB32DF2DDCD5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AD222F87-EAC5-4120-AA33-EB32DF2DDCD5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AD222F87-EAC5-4120-AA33-EB32DF2DDCD5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AD222F87-EAC5-4120-AA33-EB32DF2DDCD5}.Release|Any CPU.Build.0 = Release|Any CPU + {F4EF7157-C5F0-4444-9E49-28F6BD56295F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F4EF7157-C5F0-4444-9E49-28F6BD56295F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F4EF7157-C5F0-4444-9E49-28F6BD56295F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F4EF7157-C5F0-4444-9E49-28F6BD56295F}.Release|Any CPU.Build.0 = Release|Any CPU + {52EFDD1B-B775-49A1-BD3D-E7B7F6A989EA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {52EFDD1B-B775-49A1-BD3D-E7B7F6A989EA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {52EFDD1B-B775-49A1-BD3D-E7B7F6A989EA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {52EFDD1B-B775-49A1-BD3D-E7B7F6A989EA}.Release|Any CPU.Build.0 = Release|Any CPU + {79029F78-5113-46E4-8896-436707A7251F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {79029F78-5113-46E4-8896-436707A7251F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {79029F78-5113-46E4-8896-436707A7251F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {79029F78-5113-46E4-8896-436707A7251F}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(NestedProjects) = preSolution {552272D2-9506-4F9E-9D53-E908E53D9039} = {E7A87869-4D47-4292-BE39-77D36933088C} {4C34E3F4-718D-4E15-97A2-AE61A4ACEE02} = {E7A87869-4D47-4292-BE39-77D36933088C} + {AD222F87-EAC5-4120-AA33-EB32DF2DDCD5} = {D45462B2-C09A-4BC6-A8B1-F03C6533B084} + {F4EF7157-C5F0-4444-9E49-28F6BD56295F} = {D45462B2-C09A-4BC6-A8B1-F03C6533B084} + {52EFDD1B-B775-49A1-BD3D-E7B7F6A989EA} = {D45462B2-C09A-4BC6-A8B1-F03C6533B084} + {79029F78-5113-46E4-8896-436707A7251F} = {D45462B2-C09A-4BC6-A8B1-F03C6533B084} EndGlobalSection EndGlobal diff --git a/PSCHelpdesk.sln.DotSettings.user b/PSCHelpdesk.sln.DotSettings.user index 2134f16..4e31eb8 100644 --- a/PSCHelpdesk.sln.DotSettings.user +++ b/PSCHelpdesk.sln.DotSettings.user @@ -5,17 +5,21 @@ ForceIncluded ForceIncluded ForceIncluded + ForceIncluded ForceIncluded ForceIncluded ForceIncluded ForceIncluded + ForceIncluded ForceIncluded ForceIncluded ForceIncluded + ForceIncluded ForceIncluded ForceIncluded ForceIncluded ForceIncluded + ForceIncluded ForceIncluded ForceIncluded ForceIncluded @@ -23,26 +27,33 @@ ForceIncluded ForceIncluded ForceIncluded + ForceIncluded ForceIncluded ForceIncluded ForceIncluded + ForceIncluded ForceIncluded ForceIncluded ForceIncluded ForceIncluded ForceIncluded ForceIncluded + ForceIncluded ForceIncluded + ForceIncluded ForceIncluded ForceIncluded True - <AssemblyExplorer> - <Assembly Path="/home/thomas/.nuget/packages/hcloud-api-net/1.0.0/lib/netstandard2.0/hcloud-api.dll" /> + <AssemblyExplorer> + <Assembly Path="\home\thomas\.nuget\packages\hcloud-api-net\1.0.0\lib\netstandard2.0\hcloud-api.dll" /> + <Assembly Path="C:\Users\info\.nuget\packages\prise.pluginbridge\1.7.5\lib\netstandard2.0\Prise.PluginBridge.dll" /> + <Assembly Path="C:\Users\info\.nuget\packages\microsoft.extensions.dependencymodel\6.0.0\lib\netstandard2.0\Microsoft.Extensions.DependencyModel.dll" /> </AssemblyExplorer> True True True + \ No newline at end of file diff --git a/PSCHelpdesk/PSCHelpdesk/PSCHelpdesk.csproj b/PSCHelpdesk/PSCHelpdesk/PSCHelpdesk.csproj index 109afec..16e1850 100644 --- a/PSCHelpdesk/PSCHelpdesk/PSCHelpdesk.csproj +++ b/PSCHelpdesk/PSCHelpdesk/PSCHelpdesk.csproj @@ -18,17 +18,17 @@ - - + - + + diff --git a/PSCHelpdesk/PSCHelpdesk/Services/MenuService.cs b/PSCHelpdesk/PSCHelpdesk/Services/MenuService.cs index 336edb4..0e3a0dc 100644 --- a/PSCHelpdesk/PSCHelpdesk/Services/MenuService.cs +++ b/PSCHelpdesk/PSCHelpdesk/Services/MenuService.cs @@ -1,5 +1,5 @@ using System; -using Avalonia.Collections; +using System.Collections.Generic; using CommunityToolkit.Mvvm.DependencyInjection; using PSCHelpdesk.Shared.Menu; using PSCHelpdesk.Shared.Service; @@ -10,12 +10,12 @@ namespace PSCHelpdesk.Services; public class MenuService: ReactiveObject, IMenuService { - private AvaloniaList menuItems = new AvaloniaList(); - private AvaloniaList menuOptionItems = new AvaloniaList(); + private List menuItems = new List(); + private List menuOptionItems = new List(); public event EventHandler MenuChanged; - public AvaloniaList MenuItems + public List MenuItems { get => this.menuItems; private set => this.RaiseAndSetIfChanged(ref this.menuItems, value); @@ -24,7 +24,7 @@ public class MenuService: ReactiveObject, IMenuService /// /// Gets the list of options items shown in the hamburger menu (at the bottom). /// - public AvaloniaList MenuOptionItems + public List MenuOptionItems { get => this.menuOptionItems; private set => this.RaiseAndSetIfChanged(ref this.menuOptionItems, value); diff --git a/PSCHelpdesk/PSCHelpdesk/Services/PluginService.cs b/PSCHelpdesk/PSCHelpdesk/Services/PluginService.cs index 962e183..d05a596 100644 --- a/PSCHelpdesk/PSCHelpdesk/Services/PluginService.cs +++ b/PSCHelpdesk/PSCHelpdesk/Services/PluginService.cs @@ -59,6 +59,7 @@ public class PluginService var pluginLoader = Ioc.Default.GetService(typeof(IPluginLoader)) as IPluginLoader; var menuService = Ioc.Default.GetRequiredService(); + var testService = Ioc.Default.GetRequiredService(); var appService = Ioc.Default.GetService(typeof(AppService)) as AppService; //var settingsService = Ioc.Default.GetService(); @@ -70,10 +71,11 @@ public class PluginService var plugin = await pluginLoader.LoadPlugin(pluginToEnable, configure: (context) => { context - //.AddHostTypes(new[] {typeof(Application)}) + .AddHostService(menuService) - //.AddHostService(appService) + .AddHostService(testService) //.AddHostService(settingsService) + ; }); diff --git a/PSCHelpdesk/PSCHelpdesk/Startup.cs b/PSCHelpdesk/PSCHelpdesk/Startup.cs index 1af833e..ee5078f 100644 --- a/PSCHelpdesk/PSCHelpdesk/Startup.cs +++ b/PSCHelpdesk/PSCHelpdesk/Startup.cs @@ -14,11 +14,12 @@ class Startup var menuService = new MenuService(); var te = new ServiceCollection() - .AddPrise() .AddSingleton() .AddSingleton(menuService) + .AddSingleton(new TestService()) .AddSingleton() - .AddTransient(); + .AddTransient() + .AddPrise(); var ls = te.BuildServiceProvider(); diff --git a/PSCHelpdesk/PSCHelpdesk/ViewModels/MainWindowViewModel.cs b/PSCHelpdesk/PSCHelpdesk/ViewModels/MainWindowViewModel.cs index 4a8aa2e..e0acb61 100644 --- a/PSCHelpdesk/PSCHelpdesk/ViewModels/MainWindowViewModel.cs +++ b/PSCHelpdesk/PSCHelpdesk/ViewModels/MainWindowViewModel.cs @@ -29,14 +29,6 @@ public class MainWindowViewModel : ViewModelBase get => _selectedItem; set => SetAndRaisePropertyChanged(ref _selectedItem, value); } - - private Item _selectedContent; - public Item SelectedContent - { - get => _selectedContent; - set => SetAndRaisePropertyChanged(ref _selectedContent, value); - } - public MainWindowViewModel() { this.MenuItems = new List(); diff --git a/Shared/Service/ITestService.cs b/Shared/Service/ITestService.cs new file mode 100644 index 0000000..1d23294 --- /dev/null +++ b/Shared/Service/ITestService.cs @@ -0,0 +1,6 @@ +namespace PSCHelpdesk.Shared.Service; + +public interface ITestService +{ + public void addItem(); +} \ No newline at end of file diff --git a/Shared/Service/TestService.cs b/Shared/Service/TestService.cs new file mode 100644 index 0000000..a69f1b6 --- /dev/null +++ b/Shared/Service/TestService.cs @@ -0,0 +1,9 @@ +namespace PSCHelpdesk.Shared.Service; + +public class TestService: ITestService +{ + public void addItem() + { + throw new NotImplementedException(); + } +} \ No newline at end of file diff --git a/Shared/Shared.csproj b/Shared/Shared.csproj index 2fddace..e1c2c51 100644 --- a/Shared/Shared.csproj +++ b/Shared/Shared.csproj @@ -19,8 +19,4 @@ - - - - diff --git a/Vendor/Prise.Mvc/ApplicationBuilderExtensions.cs b/Vendor/Prise.Mvc/ApplicationBuilderExtensions.cs new file mode 100644 index 0000000..87b03d7 --- /dev/null +++ b/Vendor/Prise.Mvc/ApplicationBuilderExtensions.cs @@ -0,0 +1,14 @@ +using Microsoft.AspNetCore.Builder; +using Microsoft.Extensions.DependencyInjection; + +namespace Prise.Mvc +{ + public static class ApplicationBuilderExtensions + { + public static IApplicationBuilder EnsureStaticPluginCache(this IApplicationBuilder app) + { + app.ApplicationServices.GetRequiredService(); + return app; + } + } +} diff --git a/Vendor/Prise.Mvc/DefaultMvcPluginLoader.cs b/Vendor/Prise.Mvc/DefaultMvcPluginLoader.cs new file mode 100644 index 0000000..46d5ff5 --- /dev/null +++ b/Vendor/Prise.Mvc/DefaultMvcPluginLoader.cs @@ -0,0 +1,71 @@ +using System; +using System.IO; +using System.Threading.Tasks; +using System.Collections.Generic; + +using Prise.Caching; +using Prise.AssemblyScanning; +using Prise.AssemblyLoading; +using System.Linq; +using Prise.Utils; + +namespace Prise.Mvc +{ + public class DefaultMvcPluginLoader : IMvcPluginLoader + { + protected readonly IAssemblyScanner assemblyScanner; + protected readonly IPluginTypeSelector pluginTypeSelector; + protected readonly IAssemblyLoader assemblyLoader; + protected readonly IPluginCache pluginCache; + public DefaultMvcPluginLoader(IAssemblyScanner assemblyScanner, + IPluginTypeSelector pluginTypeSelector, + IAssemblyLoader assemblyLoader, + IPluginCache pluginCache) + { + this.assemblyScanner = assemblyScanner; + this.pluginTypeSelector = pluginTypeSelector; + this.assemblyLoader = assemblyLoader; + this.pluginCache = pluginCache; + } + + public async virtual Task> FindPlugins(string pathToPlugins) + { + return (await this.assemblyScanner.Scan(new AssemblyScannerOptions + { + StartingPath = pathToPlugins, + PluginType = typeof(T) + })); + } + + public async virtual Task LoadPluginAssembly(AssemblyScanResult plugin, Action configureLoadContext = null) + { + var pluginLoadContext = ToPluginLoadContext(plugin); + + configureLoadContext?.Invoke(pluginLoadContext); + + pluginLoadContext.AddMvcTypes(); + + var pluginAssembly = await this.assemblyLoader.Load(pluginLoadContext); + + this.pluginCache.Add(pluginAssembly, pluginLoadContext.HostServices.Select(s => s.ServiceType)); + + return pluginAssembly; + } + + public async virtual Task UnloadPluginAssembly(AssemblyScanResult plugin) + { + var pluginLoadContext = ToPluginLoadContext(plugin); + await this.assemblyLoader.Unload(pluginLoadContext); + + var pathToAssembly = Path.Combine(plugin.AssemblyPath, plugin.AssemblyName); + this.pluginCache.Remove(pathToAssembly); + } + + protected PluginLoadContext ToPluginLoadContext(AssemblyScanResult plugin) + { + var hostFramework = HostFrameworkUtils.GetHostframeworkFromHost(); + var pathToAssembly = Path.Combine(plugin.AssemblyPath, plugin.AssemblyName); + return PluginLoadContext.DefaultPluginLoadContext(pathToAssembly, typeof(T), hostFramework); + } + } +} \ No newline at end of file diff --git a/Vendor/Prise.Mvc/DefaultMvcRazorPluginLoader.cs b/Vendor/Prise.Mvc/DefaultMvcRazorPluginLoader.cs new file mode 100644 index 0000000..6ffc9cc --- /dev/null +++ b/Vendor/Prise.Mvc/DefaultMvcRazorPluginLoader.cs @@ -0,0 +1,34 @@ +using System; +using System.Threading.Tasks; + +using Prise.Caching; +using Prise.AssemblyScanning; +using Prise.AssemblyLoading; +using System.Linq; + +namespace Prise.Mvc +{ + public class DefaultMvcRazorPluginLoader : DefaultMvcPluginLoader + { + public DefaultMvcRazorPluginLoader(IAssemblyScanner assemblyScanner, + IPluginTypeSelector pluginTypeSelector, + IAssemblyLoader assemblyLoader, + IPluginCache pluginCache) : base(assemblyScanner, pluginTypeSelector, assemblyLoader, pluginCache) { } + + public override async Task LoadPluginAssembly(AssemblyScanResult plugin, Action configureLoadContext = null) + { + var pluginLoadContext = ToPluginLoadContext(plugin); + + configureLoadContext?.Invoke(pluginLoadContext); + + pluginLoadContext + .AddMvcRazorTypes(); + + var pluginAssembly = await this.assemblyLoader.Load(pluginLoadContext); + + this.pluginCache.Add(pluginAssembly, pluginLoadContext.HostServices.Select(s => s.ServiceType)); + + return pluginAssembly; + } + } +} \ No newline at end of file diff --git a/Vendor/Prise.Mvc/DefaultPriseMvcActionDescriptorChangeProvider.cs b/Vendor/Prise.Mvc/DefaultPriseMvcActionDescriptorChangeProvider.cs new file mode 100644 index 0000000..56dbb66 --- /dev/null +++ b/Vendor/Prise.Mvc/DefaultPriseMvcActionDescriptorChangeProvider.cs @@ -0,0 +1,25 @@ +using System.Threading; +using Microsoft.AspNetCore.Mvc.Infrastructure; +using Microsoft.Extensions.Primitives; + +namespace Prise.Mvc +{ + public class DefaultPriseMvcActionDescriptorChangeProvider : IActionDescriptorChangeProvider, IPriseMvcActionDescriptorChangeProvider + { + public CancellationTokenSource TokenSource { get; private set; } + + public bool HasChanged { get; set; } + + public IChangeToken GetChangeToken() + { + TokenSource = new CancellationTokenSource(); + return new CancellationChangeToken(TokenSource.Token); + } + + public void TriggerPluginChanged() + { + HasChanged = true; + TokenSource.Cancel(); + } + } +} diff --git a/Vendor/Prise.Mvc/DefaultPriseMvcControllerActivator.cs b/Vendor/Prise.Mvc/DefaultPriseMvcControllerActivator.cs new file mode 100644 index 0000000..e460e1c --- /dev/null +++ b/Vendor/Prise.Mvc/DefaultPriseMvcControllerActivator.cs @@ -0,0 +1,76 @@ +using System; +using System.Linq; +using System.Collections.Generic; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Controllers; +using Microsoft.Extensions.DependencyInjection; +using Prise.Activation; +using Prise.Infrastructure; +using Prise.Plugin; +using Prise.Proxy; +using Prise.Caching; + +namespace Prise.Mvc +{ + public class DefaultPriseMvcControllerActivator : IControllerActivator + { + public object Create(ControllerContext context) + { + var cache = context.HttpContext.RequestServices.GetRequiredService(); + var controllerType = context.ActionDescriptor.ControllerTypeInfo.AsType(); + + foreach (var cachedPluginAssembly in cache.GetAll()) + { + var pluginAssembly = cachedPluginAssembly.AssemblyShim.Assembly; + var pluginControllerType = pluginAssembly.GetTypes().FirstOrDefault(t => t.Name == controllerType.Name); + if (pluginControllerType != null) + { + var activatorContextProvider = context.HttpContext.RequestServices.GetRequiredService(); + var remotePluginActivator = context.HttpContext.RequestServices.GetRequiredService(); + var proxyCreator = context.HttpContext.RequestServices.GetRequiredService(); + var resultConverter = context.HttpContext.RequestServices.GetRequiredService(); + var parameterConverter = context.HttpContext.RequestServices.GetRequiredService(); + + object controller = null; + IPluginBootstrapper bootstrapperProxy = null; + IServiceCollection hostServices = new ServiceCollection(); + foreach (var hostServiceType in cachedPluginAssembly.HostTypes) + hostServices.Add(new ServiceDescriptor(hostServiceType, context.HttpContext.RequestServices.GetRequiredService(hostServiceType))); + + var pluginActivationContext = activatorContextProvider.ProvideActivationContext(pluginControllerType, cachedPluginAssembly.AssemblyShim); + + if (pluginActivationContext.PluginBootstrapperType != null) + { + var remoteBootstrapperInstance = remotePluginActivator.CreateRemoteBootstrapper(pluginActivationContext, hostServices); + + var remoteBootstrapperProxy = proxyCreator.CreateBootstrapperProxy(remoteBootstrapperInstance); + + bootstrapperProxy = remoteBootstrapperProxy; + } + + controller = remotePluginActivator.CreateRemoteInstance( + pluginActivationContext, + bootstrapperProxy, + hostServices: hostServices + ); + + var controllerContext = new ControllerContext(); + controllerContext.HttpContext = context.HttpContext; + var controllerContextProperty = controllerType.GetProperty("ControllerContext"); + controllerContextProperty.SetValue(controller, controllerContext); + + return controller; + } + } + + // Use MSFT's own activator utilities to create a controller instance + // This avoids us to require to register all controllers as services + return ActivatorUtilities.CreateInstance(context.HttpContext.RequestServices, controllerType); + } + + public void Release(ControllerContext context, object controller) + { + (controller as IDisposable)?.Dispose(); + } + } +} diff --git a/Vendor/Prise.Mvc/DefaultPrisePluginViewsAssemblyFileProvider.cs b/Vendor/Prise.Mvc/DefaultPrisePluginViewsAssemblyFileProvider.cs new file mode 100644 index 0000000..7d0e989 --- /dev/null +++ b/Vendor/Prise.Mvc/DefaultPrisePluginViewsAssemblyFileProvider.cs @@ -0,0 +1,72 @@ +using System; +using System.IO; +using Microsoft.Extensions.FileProviders; +using Microsoft.Extensions.Primitives; +using Prise.Caching; + +namespace Prise.Mvc +{ + public class DefaultPrisePluginViewsAssemblyFileProvider : IFileProvider + { + protected readonly PhysicalFileProvider webRootFileProvider; + protected readonly string pathToPlugins; + public DefaultPrisePluginViewsAssemblyFileProvider(string hostingRootPath, string pathToPlugins) + { + if (!Path.IsPathRooted(pathToPlugins)) + throw new ArgumentException($"{nameof(pathToPlugins)} must be rooted (absolute path)."); + + this.pathToPlugins = pathToPlugins; + this.webRootFileProvider = new PhysicalFileProvider(hostingRootPath); + } + + private IPluginCache GetLoadedPluginsCache() + { + return DefaultStaticPluginCacheAccessor.CurrentCache; + } + + private IFileProvider GetPluginFileProvider(string subpath) + { + var cache = GetLoadedPluginsCache(); + if (cache == null) + return null; + + foreach (var loadedPlugin in cache.GetAll()) + { + var pluginAssemblyName = loadedPlugin.AssemblyShim.Assembly.GetName().Name; + var pathToPlugin = Path.Combine(pathToPlugins, pluginAssemblyName); + var pathCandidate = Path.Combine(pathToPlugin, SanitizeSubPath(subpath)); + if (File.Exists(pathCandidate)) + return new PhysicalFileProvider(pathToPlugin); + } + return null; + } + + private string SanitizeSubPath(string subPath) + { + if (subPath.StartsWith('/')) + return subPath.Substring(1); + return subPath; + } + + public IDirectoryContents GetDirectoryContents(string subpath) + { + var pluginFileProvider = GetPluginFileProvider(subpath); + if (pluginFileProvider != null) + return pluginFileProvider.GetDirectoryContents(subpath); + return this.webRootFileProvider.GetDirectoryContents(subpath); + } + + public IFileInfo GetFileInfo(string subpath) + { + var pluginFileProvider = GetPluginFileProvider(subpath); + if (pluginFileProvider != null) + return pluginFileProvider.GetFileInfo(subpath); + return this.webRootFileProvider.GetFileInfo(subpath); + } + + public IChangeToken Watch(string filter) + { + return this.webRootFileProvider.Watch(filter); + } + } +} diff --git a/Vendor/Prise.Mvc/DefaultStaticPluginCacheAccessor.cs b/Vendor/Prise.Mvc/DefaultStaticPluginCacheAccessor.cs new file mode 100644 index 0000000..8900ad0 --- /dev/null +++ b/Vendor/Prise.Mvc/DefaultStaticPluginCacheAccessor.cs @@ -0,0 +1,9 @@ +using Prise.Caching; + +namespace Prise.Mvc +{ + public static class DefaultStaticPluginCacheAccessor + { + public static IPluginCache CurrentCache { get; internal set; } + } +} diff --git a/Vendor/Prise.Mvc/DefaultStaticPluginCacheAccessorBootstrapper.cs b/Vendor/Prise.Mvc/DefaultStaticPluginCacheAccessorBootstrapper.cs new file mode 100644 index 0000000..99b5fd1 --- /dev/null +++ b/Vendor/Prise.Mvc/DefaultStaticPluginCacheAccessorBootstrapper.cs @@ -0,0 +1,23 @@ +using System; +using Prise.Caching; + +namespace Prise.Mvc +{ + public class DefaultStaticPluginCacheAccessorBootstrapper : IPluginCacheAccessorBootstrapper + { + protected bool isBootstrapped; + public DefaultStaticPluginCacheAccessorBootstrapper(IPluginCache cache) + { + if (this.isBootstrapped) + throw new NotSupportedException($"IPluginCache was already bootstrapped"); + + this.SetCurrentCache(cache); + this.isBootstrapped = true; + } + + public void SetCurrentCache(IPluginCache cache) + { + DefaultStaticPluginCacheAccessor.CurrentCache = cache; + } + } +} diff --git a/Vendor/Prise.Mvc/IMvcPluginLoader.cs b/Vendor/Prise.Mvc/IMvcPluginLoader.cs new file mode 100644 index 0000000..66c06f8 --- /dev/null +++ b/Vendor/Prise.Mvc/IMvcPluginLoader.cs @@ -0,0 +1,14 @@ +using System; +using System.Threading.Tasks; +using System.Collections.Generic; + + +namespace Prise.Mvc +{ + public interface IMvcPluginLoader + { + Task> FindPlugins(string pathToPlugins); + Task LoadPluginAssembly(AssemblyScanResult plugin, Action configure = null); + Task UnloadPluginAssembly(AssemblyScanResult plugin); + } +} \ No newline at end of file diff --git a/Vendor/Prise.Mvc/IPluginCacheAccessorBootstrapper.cs b/Vendor/Prise.Mvc/IPluginCacheAccessorBootstrapper.cs new file mode 100644 index 0000000..1c2f5b6 --- /dev/null +++ b/Vendor/Prise.Mvc/IPluginCacheAccessorBootstrapper.cs @@ -0,0 +1,9 @@ +using Prise.Caching; + +namespace Prise.Mvc +{ + public interface IPluginCacheAccessorBootstrapper + { + void SetCurrentCache(IPluginCache cache); + } +} diff --git a/Vendor/Prise.Mvc/IPriseMvcActionDescriptorChangeProvider.cs b/Vendor/Prise.Mvc/IPriseMvcActionDescriptorChangeProvider.cs new file mode 100644 index 0000000..2d03770 --- /dev/null +++ b/Vendor/Prise.Mvc/IPriseMvcActionDescriptorChangeProvider.cs @@ -0,0 +1,7 @@ +namespace Prise.Mvc +{ + public interface IPriseMvcActionDescriptorChangeProvider + { + void TriggerPluginChanged(); + } +} diff --git a/Vendor/Prise.Mvc/PluginAssemblyPart.cs b/Vendor/Prise.Mvc/PluginAssemblyPart.cs new file mode 100644 index 0000000..f92ff61 --- /dev/null +++ b/Vendor/Prise.Mvc/PluginAssemblyPart.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using Microsoft.AspNetCore.Mvc.ApplicationParts; + +namespace Prise.Mvc +{ + public class PluginAssemblyPart : AssemblyPart, ICompilationReferencesProvider + { + public PluginAssemblyPart(Assembly assembly) : base(assembly) { } + + // This solves the NullRef bug for in-memory assemblies from Prise + IEnumerable ICompilationReferencesProvider.GetReferencePaths() => Array.Empty(); + } +} diff --git a/Vendor/Prise.Mvc/Prise.Mvc.csproj b/Vendor/Prise.Mvc/Prise.Mvc.csproj new file mode 100644 index 0000000..7f1c0cd --- /dev/null +++ b/Vendor/Prise.Mvc/Prise.Mvc.csproj @@ -0,0 +1,98 @@ + + + + netcoreapp2.1;netcoreapp3.1;net5.0;net6.0 + Prise.Mvc + Prise.Mvc + Adds ASP.NET MVC features to an existing Prise setup! + Maarten Merken + MRKN + mvc;controllers;plugin + https://raw.githubusercontent.com/merken/Prise/master/LICENSE + https://github.com/merken/Prise + https://github.com/merken/Prise.git + git + $(TargetsForTfmSpecificBuildOutput);CopyProjectReferencesToPackage + + + + + + + + + + NETCORE2_1 + + + + + + NETCORE3_1 + + + + icon.png + true + + + + + True + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + Prise.Plugin.dll + + + true + Prise.Proxy.dll + + + true + Prise.dll + + + + diff --git a/Vendor/Prise.Mvc/PriseMvcExtensions.cs b/Vendor/Prise.Mvc/PriseMvcExtensions.cs new file mode 100644 index 0000000..81ffbcd --- /dev/null +++ b/Vendor/Prise.Mvc/PriseMvcExtensions.cs @@ -0,0 +1,118 @@ +using System; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Controllers; +using Microsoft.AspNetCore.Mvc.Infrastructure; +using Microsoft.AspNetCore.Mvc.Razor; +#if !NETCORE2_1 +using Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation; +#endif +using Microsoft.AspNetCore.Mvc.ViewFeatures; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; +using Prise.DependencyInjection; + +using Prise.Activation; +using Prise.AssemblyLoading; +using Prise.AssemblyScanning; +using Prise.Proxy; +using Prise.Caching; + +namespace Prise.Mvc +{ + public static class PriseMvcExtensions + { + internal static PluginLoadContext AddMvcTypes(this PluginLoadContext loadContext) + { + return loadContext.AddHostTypes(new[] { typeof(ControllerBase) }); + } + + internal static PluginLoadContext AddMvcRazorTypes(this PluginLoadContext loadContext) + { + return loadContext.AddHostTypes(new[] { typeof(ControllerBase), typeof(ITempDataDictionaryFactory) }); + } + + public static IServiceCollection AddCorePriseServices(this IServiceCollection services) + { + return services + .AddFactory(DefaultFactories.DefaultAssemblyScanner, ServiceLifetime.Scoped) + .AddFactory(DefaultFactories.DefaultPluginTypeSelector, ServiceLifetime.Scoped) + .AddFactory(DefaultFactories.DefaultParameterConverter, ServiceLifetime.Scoped) + .AddFactory(DefaultFactories.DefaultResultConverter, ServiceLifetime.Scoped) + .AddFactory(DefaultFactories.DefaultPluginActivationContextProvider, ServiceLifetime.Scoped) + .AddFactory(DefaultFactories.DefaultRemotePluginActivator, ServiceLifetime.Scoped) + .AddFactory(DefaultFactories.DefaultPluginProxyCreator, ServiceLifetime.Scoped) + .AddFactory(DefaultFactories.DefaultAssemblyLoader, ServiceLifetime.Singleton); + } + + /// + /// Does all of the plumbing to load API Controllers as Prise Plugins. + /// Limitiations: + /// - No DispatchProxy can be used, backwards compatability is compromised (DispatchProxy requires an interface as base class, not ControllerBase) + /// - Plugin Cache is set to Singleton because we cannot unload assemblies, this would disable the controller routing (and result in 404) + /// - Assembly unloading is disabled, memory leaks can occur + /// + /// A fully configured Prise setup that allows you to load plugins via the IMvcPluginLoader + public static IServiceCollection AddPriseMvc(this IServiceCollection services) + { + + return services + .AddCorePriseServices() + .AddSingleton() + .AddScoped() + .ConfigureMvcServices() + ; + } + + /// + /// Does all of the plumbing to load API Controllers and RAZOR Controllers as Prise Plugins. + /// Limitiations: + /// - No DispatchProxy can be used, backwards compatability is compromised (DispatchProxy requires an interface as base class, not ControllerBase) + /// - Plugin Cache is set to Singleton because we cannot unload assemblies, this would disable the controller routing (and result in 404) + /// - Assembly unloading is disabled, memory leaks can occur + /// + /// + /// + /// By default, this should be the IWebHostEnvironment.WebRootPaht or IHostingEnvironment.WebRootPath + /// + public static IServiceCollection AddPriseRazorPlugins(this IServiceCollection services, string webRootPath, string pathToPlugins) + { + return services + .AddCorePriseServices() + .AddSingleton() + .AddScoped() + .ConfigureMvcServices() + .ConfigureRazorServices(webRootPath, pathToPlugins) + ; + } + + private static IServiceCollection ConfigureMvcServices(this IServiceCollection services) + { + var actionDescriptorChangeProvider = new DefaultPriseMvcActionDescriptorChangeProvider(); + // Registers the change provider + return services + .AddSingleton(actionDescriptorChangeProvider) + .AddSingleton(actionDescriptorChangeProvider) + // Registers the activator for controllers from plugin assemblies + .Replace(ServiceDescriptor.Transient()); + } + + private static IServiceCollection ConfigureRazorServices(this IServiceCollection services, string webRootPath, string pathToPlugins) + { + return services +#if NETCORE2_1 + .Configure(options => + { + options.FileProviders.Add(new DefaultPrisePluginViewsAssemblyFileProvider(webRootPath, pathToPlugins)); + }) +#else + .Configure(options => + { + options.FileProviders.Add(new DefaultPrisePluginViewsAssemblyFileProvider(webRootPath, pathToPlugins)); + }) +#endif + // Registers the static Plugin Cache Accessor + .AddSingleton(); + } + + } +} diff --git a/Vendor/Prise.Plugin/BootstrapperServiceAttribute.cs b/Vendor/Prise.Plugin/BootstrapperServiceAttribute.cs new file mode 100644 index 0000000..023b96e --- /dev/null +++ b/Vendor/Prise.Plugin/BootstrapperServiceAttribute.cs @@ -0,0 +1,30 @@ +using System; + +namespace Prise.Plugin +{ + [System.AttributeUsage(System.AttributeTargets.Field, Inherited = false, AllowMultiple = false)] + public sealed class BootstrapperServiceAttribute : System.Attribute + { + Type serviceType; + public Type ServiceType + { + get { return this.serviceType; } + set { this.serviceType = value; } + } + + Type bridgeType; + [Obsolete("Usage of a BridgeType is obsolete, please use ProxyType instead. Existing plugins will continue to function as normal.", false)] + public Type BridgeType + { + get { return this.bridgeType; } + set { this.bridgeType = value; } + } + + Type proxyType; + public Type ProxyType + { + get { return this.proxyType; } + set { this.proxyType = value; } + } + } +} \ No newline at end of file diff --git a/Vendor/Prise.Plugin/IPluginBootstrapper.cs b/Vendor/Prise.Plugin/IPluginBootstrapper.cs new file mode 100644 index 0000000..54dfd23 --- /dev/null +++ b/Vendor/Prise.Plugin/IPluginBootstrapper.cs @@ -0,0 +1,9 @@ +using Microsoft.Extensions.DependencyInjection; + +namespace Prise.Plugin +{ + public interface IPluginBootstrapper + { + IServiceCollection Bootstrap(IServiceCollection services); + } +} \ No newline at end of file diff --git a/Vendor/Prise.Plugin/PluginActivatedAttribute.cs b/Vendor/Prise.Plugin/PluginActivatedAttribute.cs new file mode 100644 index 0000000..ecc9ede --- /dev/null +++ b/Vendor/Prise.Plugin/PluginActivatedAttribute.cs @@ -0,0 +1,5 @@ +namespace Prise.Plugin +{ + [System.AttributeUsage(System.AttributeTargets.Method, Inherited = false, AllowMultiple = false)] + public sealed class PluginActivatedAttribute : System.Attribute { } +} diff --git a/Vendor/Prise.Plugin/PluginAttribute.cs b/Vendor/Prise.Plugin/PluginAttribute.cs new file mode 100644 index 0000000..21ce1a9 --- /dev/null +++ b/Vendor/Prise.Plugin/PluginAttribute.cs @@ -0,0 +1,15 @@ +using System; + +namespace Prise.Plugin +{ + [System.AttributeUsage(System.AttributeTargets.Class, Inherited = false, AllowMultiple = false)] + public sealed class PluginAttribute : System.Attribute + { + Type pluginType; + public Type PluginType + { + get { return this.pluginType; } + set { this.pluginType = value; } + } + } +} \ No newline at end of file diff --git a/Vendor/Prise.Plugin/PluginBootstrapperAttribute.cs b/Vendor/Prise.Plugin/PluginBootstrapperAttribute.cs new file mode 100644 index 0000000..1647e0b --- /dev/null +++ b/Vendor/Prise.Plugin/PluginBootstrapperAttribute.cs @@ -0,0 +1,15 @@ +using System; + +namespace Prise.Plugin +{ + [System.AttributeUsage(System.AttributeTargets.Class, Inherited = false, AllowMultiple = true)] + public sealed class PluginBootstrapperAttribute : System.Attribute + { + Type pluginType; + public Type PluginType + { + get { return this.pluginType; } + set { this.pluginType = value; } + } + } +} \ No newline at end of file diff --git a/Vendor/Prise.Plugin/PluginFactoryAttribute.cs b/Vendor/Prise.Plugin/PluginFactoryAttribute.cs new file mode 100644 index 0000000..b3726c3 --- /dev/null +++ b/Vendor/Prise.Plugin/PluginFactoryAttribute.cs @@ -0,0 +1,8 @@ +using System; + +namespace Prise.Plugin +{ + [Obsolete("Usage of a PluginFactory is obsolete, please use field injection instead. Existing plugins will continue to function as normal.", false)] + [System.AttributeUsage(System.AttributeTargets.Method, Inherited = false, AllowMultiple = false)] + public sealed class PluginFactoryAttribute : System.Attribute { } +} \ No newline at end of file diff --git a/Vendor/Prise.Plugin/PluginServiceAttribute.cs b/Vendor/Prise.Plugin/PluginServiceAttribute.cs new file mode 100644 index 0000000..d8e88d2 --- /dev/null +++ b/Vendor/Prise.Plugin/PluginServiceAttribute.cs @@ -0,0 +1,37 @@ +using System; + +namespace Prise.Plugin +{ + [System.AttributeUsage(System.AttributeTargets.Field, Inherited = false, AllowMultiple = false)] + public sealed class PluginServiceAttribute : System.Attribute + { + Type serviceType; + public Type ServiceType + { + get { return this.serviceType; } + set { this.serviceType = value; } + } + + ProvidedBy providedBy; + public ProvidedBy ProvidedBy + { + get { return this.providedBy; } + set { this.providedBy = value; } + } + + Type bridgeType; + [Obsolete("Usage of a BridgeType is obsolete, please use ProxyType instead. Existing plugins will continue to function as normal.", false)] + public Type BridgeType + { + get { return this.bridgeType; } + set { this.bridgeType = value; } + } + + Type proxyType; + public Type ProxyType + { + get { return this.proxyType; } + set { this.proxyType = value; } + } + } +} \ No newline at end of file diff --git a/Vendor/Prise.Plugin/Prise.Plugin.csproj b/Vendor/Prise.Plugin/Prise.Plugin.csproj new file mode 100644 index 0000000..20503f8 --- /dev/null +++ b/Vendor/Prise.Plugin/Prise.Plugin.csproj @@ -0,0 +1,32 @@ + + + + net9.0 + Prise.Plugin + Prise.Plugin + Prise, A .NET Plugin Framework! + Maarten Merken + MRKN + plugin;framework;prise;decoupling;assembly;dispatchproxy;proxy + https://raw.githubusercontent.com/merken/Prise/master/LICENSE + https://github.com/merken/Prise + https://github.com/merken/Prise.git + git + default + + + + icon.png + + + + + True + + + + + + + + diff --git a/Vendor/Prise.Plugin/ProvidedBy.cs b/Vendor/Prise.Plugin/ProvidedBy.cs new file mode 100644 index 0000000..78bd929 --- /dev/null +++ b/Vendor/Prise.Plugin/ProvidedBy.cs @@ -0,0 +1,8 @@ +namespace Prise.Plugin +{ + public enum ProvidedBy + { + Plugin = 0, + Host + } +} \ No newline at end of file diff --git a/Vendor/Prise.Proxy/Infrastructure/IParameterConverter.cs b/Vendor/Prise.Proxy/Infrastructure/IParameterConverter.cs new file mode 100644 index 0000000..d149656 --- /dev/null +++ b/Vendor/Prise.Proxy/Infrastructure/IParameterConverter.cs @@ -0,0 +1,9 @@ +using System; + +namespace Prise.Proxy +{ + public interface IParameterConverter : IDisposable + { + object ConvertToRemoteType(Type localType, object value); + } +} diff --git a/Vendor/Prise.Proxy/Infrastructure/IResultConverter.cs b/Vendor/Prise.Proxy/Infrastructure/IResultConverter.cs new file mode 100644 index 0000000..cd2c758 --- /dev/null +++ b/Vendor/Prise.Proxy/Infrastructure/IResultConverter.cs @@ -0,0 +1,28 @@ +using System; +using System.Threading.Tasks; + +namespace Prise.Proxy +{ + public interface IResultConverter : IDisposable + { + /// + /// This method should convert a remote value into a local one. + /// This method will be called in case the remote type is not a Task. + /// + /// The return type of the host + /// The return type of the remote + /// The value from the remote, this can be different from the remoteType if the remote uses an old contract, in this case, convert to correct type. + /// A converted local instance + object ConvertToLocalType(Type localType, Type remoteType, object value); + + /// + /// This method should convert a remote value into a local one. + /// This method will be called in case the remote type is a Task. + /// + /// The return type of the host, Task + /// The return type of the remote, Task + /// The Task that holds the value from the remote, this can be different from the remoteType if the remote uses an old contract, in this case, convert to correct type. + /// A Task containing the local type with the remote value + object ConvertToLocalTypeAsync(Type localType, Type remoteType, Task task); + } +} diff --git a/Vendor/Prise.Proxy/Method.cs b/Vendor/Prise.Proxy/Method.cs new file mode 100644 index 0000000..b2b8b8b --- /dev/null +++ b/Vendor/Prise.Proxy/Method.cs @@ -0,0 +1,16 @@ +using System; + +namespace Prise.Proxy +{ + public struct Method + { + public string Name { get; } + public Type? ReturnType { get; } + + public Method(string name, Type? returnType = null) + { + this.Name = name; + this.ReturnType = returnType; + } + } +} \ No newline at end of file diff --git a/Vendor/Prise.Proxy/MethodFindingStrategy.cs b/Vendor/Prise.Proxy/MethodFindingStrategy.cs new file mode 100644 index 0000000..62fcc06 --- /dev/null +++ b/Vendor/Prise.Proxy/MethodFindingStrategy.cs @@ -0,0 +1,13 @@ +using System; + +namespace Prise.Proxy +{ + [Flags] + public enum MethodFindingStrategy + { + MethodNameMustMatch, + MethodReturnTypeMustMatch, + ParameterCountMustMatch, + ParameterTypeMustMatch + } +} \ No newline at end of file diff --git a/Vendor/Prise.Proxy/Parameter.cs b/Vendor/Prise.Proxy/Parameter.cs new file mode 100644 index 0000000..d6a1d51 --- /dev/null +++ b/Vendor/Prise.Proxy/Parameter.cs @@ -0,0 +1,16 @@ +using System; + +namespace Prise.Proxy +{ + public struct Parameter + { + public string Name { get; } + public Type? Type { get; } + + public Parameter(string name, Type? type = null) + { + this.Name = name; + this.Type = type; + } + } +} \ No newline at end of file diff --git a/Vendor/Prise.Proxy/PassthroughParameterConverter.cs b/Vendor/Prise.Proxy/PassthroughParameterConverter.cs new file mode 100644 index 0000000..1a02b0b --- /dev/null +++ b/Vendor/Prise.Proxy/PassthroughParameterConverter.cs @@ -0,0 +1,29 @@ +using System; + +namespace Prise.Proxy +{ + public class PassthroughParameterConverter : IParameterConverter + { + protected bool disposed = false; + + public object ConvertToRemoteType(Type localType, object value) + { + return value; + } + + protected virtual void Dispose(bool disposing) + { + if (!this.disposed && disposing) + { + // Nothing to do here + } + this.disposed = true; + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + } +} \ No newline at end of file diff --git a/Vendor/Prise.Proxy/PassthroughResultConverter.cs b/Vendor/Prise.Proxy/PassthroughResultConverter.cs new file mode 100644 index 0000000..d998ae1 --- /dev/null +++ b/Vendor/Prise.Proxy/PassthroughResultConverter.cs @@ -0,0 +1,12 @@ +using System; + +namespace Prise.Proxy +{ + public class PassthroughResultConverter : ResultConverter + { + public override object Deserialize(Type localType, Type remoteType, object value) + { + return value; + } + } +} \ No newline at end of file diff --git a/Vendor/Prise.Proxy/Prise.Proxy.csproj b/Vendor/Prise.Proxy/Prise.Proxy.csproj new file mode 100644 index 0000000..74983f6 --- /dev/null +++ b/Vendor/Prise.Proxy/Prise.Proxy.csproj @@ -0,0 +1,42 @@ + + + + net9.0 + Prise.Proxy + Prise.Proxy + Prise, A .NET Plugin Framework! + Maarten Merken + MRKN + plugin;framework;prise;decoupling;assembly;dispatchproxy;proxy + $(TargetsForTfmSpecificBuildOutput);CopyProjectReferencesToPackage + enable + default + https://raw.githubusercontent.com/merken/Prise/master/LICENSE + https://github.com/merken/Prise + https://github.com/merken/Prise.git + git + + + + + + + + + + + + + + icon.png + true + + + + + True + + + + + diff --git a/Vendor/Prise.Proxy/PriseProxy.cs b/Vendor/Prise.Proxy/PriseProxy.cs new file mode 100644 index 0000000..c90fd83 --- /dev/null +++ b/Vendor/Prise.Proxy/PriseProxy.cs @@ -0,0 +1,254 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; + +namespace Prise.Proxy +{ + /// + /// This is the PriseProxy static class that encapsulates most of the boilerplate static methods in order to interact with the remote object (Plugin) + /// TODO + /// - Generic Methods (Task Do(T stuff)) + /// - Events (not sure if this is ever possible) + /// + public static class PriseProxy + { + public static object Invoke(object remoteObject, MethodInfo targetMethod, object[] args) + => Invoke(remoteObject, targetMethod, args, new PassthroughParameterConverter(), + new PassthroughResultConverter()); + + public static object Invoke(object remoteObject, MethodInfo targetMethod, object[] args, + IParameterConverter parameterConverter, IResultConverter resultConverter) + { + try + { + var localType = targetMethod.ReturnType; + var remoteMethod = FindMethodOnObject(targetMethod, remoteObject); + if (remoteMethod == null) + throw new PriseProxyException( + $"Target method {targetMethod.Name} is not found on Proxy Type {remoteObject.GetType().Name}."); + + object result = null; + if (remoteMethod.IsGenericMethod) + { + var generic = remoteMethod.MakeGenericMethod(targetMethod.GetGenericArguments()); + result = generic.Invoke(remoteObject, SerializeParameters(parameterConverter, remoteMethod, args)); + } + else + result = remoteMethod.Invoke(remoteObject, + SerializeParameters(parameterConverter, remoteMethod, args)); + + var remoteType = remoteMethod.ReturnType; + if (remoteType.BaseType == typeof(System.Threading.Tasks.Task)) + return resultConverter.ConvertToLocalTypeAsync(localType, remoteType, + result as System.Threading.Tasks.Task); + + if (remoteType == typeof(System.Threading.Tasks.Task)) + return resultConverter.ConvertToLocalTypeAsync(localType, remoteType, + result as System.Threading.Tasks.Task); + + + if (remoteType == typeof(void)) + return null; + + return resultConverter.ConvertToLocalType(localType, remoteType, result); + } + catch (Exception ex) when (ex is TargetInvocationException) + { + throw ex.InnerException ?? ex; + } + } + + public static MethodInfo FindMethodOnObject(MethodInfo callingMethod, object targetObject) + => FindMethodOnObject( + targetObject, + new Method(callingMethod.Name, callingMethod.ReturnType), + callingMethod.GetParameters().Select(p => new Parameter(p.Name, p.ParameterType)).ToArray(), + throwOnError: true)!; // Throws error when null + + public static MethodInfo? TryFindMethodOnObject(MethodInfo callingMethod, object targetObject) + => FindMethodOnObject( + targetObject, + new Method(callingMethod.Name, callingMethod.ReturnType), + callingMethod.GetParameters().Select(p => new Parameter(p.Name, p.ParameterType)).ToArray()); + + public static MethodInfo? FindMethodOnObject( + object targetObject, + Method method, + Parameter[] parameters, + MethodFindingStrategy strategy = MethodFindingStrategy.MethodNameMustMatch | + MethodFindingStrategy.MethodReturnTypeMustMatch | + MethodFindingStrategy.ParameterCountMustMatch | + MethodFindingStrategy.ParameterTypeMustMatch, + bool throwOnError = false) + { + bool isNameCorrect(MethodInfo targetMethod) => targetMethod.Name == method.Name; + + // First, find by method name + var targetMethods = targetObject.GetType().GetMethods().AsEnumerable(); + if (strategy.HasFlag(MethodFindingStrategy.MethodNameMustMatch)) + targetMethods = targetMethods.Where(isNameCorrect); + + if (!targetMethods.Any()) + if (throwOnError) + throw new PriseProxyException( + $"Target method {method.Name} is not found on Proxy Type {targetObject.GetType().Name}."); + else + return null; + + if (targetMethods.Count() == 1) + return targetMethods.First(); + + bool isReturnTypeCorrect(MethodInfo targetMethod) => targetMethod.ReturnType == method.ReturnType; + + if (strategy.HasFlag(MethodFindingStrategy.MethodReturnTypeMustMatch)) + // Second, find by method name AND return type + targetMethods = targetMethods.Where(isReturnTypeCorrect); + + if (targetMethods.Count() == 1) + return targetMethods.First(); + + bool isParameterCountCorrect(MethodInfo targetMethod) => + targetMethod.GetParameters().Count() == parameters.Length; + + bool doAllParametersMatch(MethodInfo targetMethod) + { + var callingMethodParameters = parameters; + var targetMethodParameters = targetMethod.GetParameters(); + for (var index = 0; index < callingMethodParameters.Count(); index++) + { + var callingParam = callingMethodParameters[index]; + if (callingParam.Type is null) + throw new PriseProxyException( + $"When using {nameof(MethodFindingStrategy.ParameterTypeMustMatch)}, Parameter.Type must be provided"); + var targetParam = targetMethodParameters[index]; + if (!(targetParam.Name == callingParam.Name && + targetParam.ParameterType.Name == callingParam.Type.Name)) + return false; + } + + return true; + } + + targetMethods = targetMethods.Where(targetMethod => + (!strategy.HasFlag(MethodFindingStrategy.ParameterCountMustMatch) || + isParameterCountCorrect(targetMethod)) && + (!strategy.HasFlag(MethodFindingStrategy.ParameterTypeMustMatch) || doAllParametersMatch(targetMethod)) + ); + + if (!targetMethods.Any()) + if (throwOnError) + throw new PriseProxyException( + $"Target method {method.Name} is not found on Proxy Type {targetObject.GetType().Name}."); + else + return null; + + if (targetMethods.Count() > 1) + if (throwOnError) + throw new PriseProxyException( + $"Target method {method.Name} could not be determined on object {targetObject.GetType().Name}."); + else + return null; + + return targetMethods.First(); + } + + internal static object[] SerializeParameters(IParameterConverter parameterConverter, MethodInfo targetMethod, + object[] args) + { + var parameters = targetMethod.GetParameters(); + var results = new List(); + + for (var index = 0; index < parameters.Count(); index++) + { + var parameter = parameters[index]; + var parameterValue = args[index]; + + if (parameter.ParameterType.BaseType == typeof(System.MulticastDelegate)) + { + if (parameter.ParameterType.GenericTypeArguments.Any(g => g != typeof(EventArgs))) + throw new PriseProxyException($"Custom EventArgs are not supported in Prise"); + + results.Add(parameterValue); + continue; + } + + object result = null; + if (parameter.ParameterType.IsGenericParameter) + { + var runtimeType = parameterValue.GetType(); + result = parameterConverter.ConvertToRemoteType(runtimeType, parameterValue); + } + else + result = parameterConverter.ConvertToRemoteType(parameter.ParameterType, parameterValue); + + results.Add(result); + } + + return results.ToArray(); + } + } + + /// + /// This is the PriseProxy wrapper class that will acts as the communication layer between the Host and the Plugin. + /// Every call from the Host to the Plugin will go through here. + /// + /// The Plugin type + public class PriseProxy : DispatchProxy, IDisposable + { + private IParameterConverter parameterConverter; + private IResultConverter resultConverter; + private object remoteObject; + protected bool disposed = false; + + protected override object Invoke(MethodInfo targetMethod, object[] args) => PriseProxy.Invoke(this.remoteObject, + targetMethod, args, this.parameterConverter, this.resultConverter); + + public static object Create() => Create>(); + + internal PriseProxy SetRemoteObject(object remoteObject) + { + if (remoteObject == null) + throw new PriseProxyException($"Remote object for Proxy<{typeof(T).Name}> was null"); + + this.remoteObject = remoteObject; + return this; + } + + internal PriseProxy SetParameterConverter(IParameterConverter parameterConverter) + { + if (parameterConverter == null) + throw new PriseProxyException($"IParameterConverter for Proxy<{typeof(T).Name}> was null"); + + this.parameterConverter = parameterConverter; + return this; + } + + internal PriseProxy SetResultConverter(IResultConverter resultConverter) + { + if (resultConverter == null) + throw new PriseProxyException($"IResultConverter for Proxy<{typeof(T).Name}> was null"); + + this.resultConverter = resultConverter; + return this; + } + + protected virtual void Dispose(bool disposing) + { + if (!this.disposed && disposing) + { + this.parameterConverter = null; + this.resultConverter = null; + this.remoteObject = null; + } + + this.disposed = true; + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + } +} \ No newline at end of file diff --git a/Vendor/Prise.Proxy/PriseProxyException.cs b/Vendor/Prise.Proxy/PriseProxyException.cs new file mode 100644 index 0000000..60bed2f --- /dev/null +++ b/Vendor/Prise.Proxy/PriseProxyException.cs @@ -0,0 +1,25 @@ +using System; +using System.Runtime.Serialization; + +namespace Prise.Proxy +{ + [Serializable] + public class PriseProxyException : Exception + { + public PriseProxyException(string message) : base(message) + { + } + + public PriseProxyException(string message, Exception innerException) : base(message, innerException) + { + } + + public PriseProxyException() + { + } + + protected PriseProxyException(SerializationInfo info, StreamingContext context) : base(info, context) + { + } + } +} diff --git a/Vendor/Prise.Proxy/ProxyCreator.cs b/Vendor/Prise.Proxy/ProxyCreator.cs new file mode 100644 index 0000000..2eecd82 --- /dev/null +++ b/Vendor/Prise.Proxy/ProxyCreator.cs @@ -0,0 +1,32 @@ +using System; + +namespace Prise.Proxy +{ + public static class ProxyCreator + { + public static object CreateGenericProxy(Type proxyType, object remoteObject) + { + return typeof(ProxyCreator).GetMethod(nameof(ProxyCreator.CreateProxy)).MakeGenericMethod(proxyType).Invoke(null, new[] { remoteObject, null, null }); + } + + public static TProxyType CreateProxy( + object remoteObject, + IParameterConverter parameterConverter = null, + IResultConverter resultConverter = null) + { + if (parameterConverter == null) + parameterConverter = new PassthroughParameterConverter(); + + if (resultConverter == null) + resultConverter = new PassthroughResultConverter(); + + var proxy = PriseProxy.Create(); + ((PriseProxy)proxy) + .SetRemoteObject(remoteObject) + .SetParameterConverter(parameterConverter) + .SetResultConverter(resultConverter); + + return (TProxyType)proxy; + } + } +} diff --git a/Vendor/Prise.Proxy/ResultConverter.cs b/Vendor/Prise.Proxy/ResultConverter.cs new file mode 100644 index 0000000..282c692 --- /dev/null +++ b/Vendor/Prise.Proxy/ResultConverter.cs @@ -0,0 +1,63 @@ +using System; +using System.Linq; +using System.Reflection; +using System.Threading.Tasks; + +namespace Prise.Proxy +{ + public abstract class ResultConverter : IResultConverter + { + private bool disposed = false; + public abstract object Deserialize(Type localType, Type remoteType, object value); + public object ConvertToLocalType(Type localType, Type remoteType, object value) + { + return Deserialize(localType, remoteType, value); + } + + public object ConvertToLocalTypeAsync(Type localType, Type remoteType, Task task) + { + var taskResultType = localType.GenericTypeArguments != null && localType.GenericTypeArguments.Any() ? localType.GenericTypeArguments[0] : null; + var taskCompletionSource = new TaskCompletionSource(taskResultType ?? typeof(object)); + + task.ContinueWith(t => + { + if (t.IsCanceled) + taskCompletionSource.TrySetCanceled(); + else if (t.IsFaulted) + taskCompletionSource.TrySetException(t.Exception); + else if (taskResultType == null) + taskCompletionSource.TrySetResult(null); + else + { + var property = t.GetType() + .GetTypeInfo() + .GetProperties() + .FirstOrDefault(p => p.Name == "Result"); + + if (property != null) + { + var value = Deserialize(localType, remoteType, property.GetValue(task)); + taskCompletionSource.TrySetResult(value); + } + } + }); + + return taskCompletionSource.Task; + } + + protected virtual void Dispose(bool disposing) + { + if (!this.disposed && disposing) + { + // Nothing to do here + } + this.disposed = true; + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + } +} \ No newline at end of file diff --git a/Vendor/Prise.Proxy/TaskCompletionSource.cs b/Vendor/Prise.Proxy/TaskCompletionSource.cs new file mode 100644 index 0000000..b040404 --- /dev/null +++ b/Vendor/Prise.Proxy/TaskCompletionSource.cs @@ -0,0 +1,56 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Threading.Tasks; + +namespace Prise.Proxy +{ + /// + /// This is a non-generic TaskCompletionSource + /// It allows you to set a type via its constructor + /// + public class TaskCompletionSource + { + private readonly Type type; + private readonly object taskCompletionSource; + + public TaskCompletionSource(Type type) + { + this.type = type; + this.taskCompletionSource = typeof(TaskCompletionSource<>) + .MakeGenericType(type) + .GetConstructors(BindingFlags.Public | BindingFlags.Instance)[0] + .Invoke(null); + } + + public bool TrySetCanceled() + { + var trySetCanceled = taskCompletionSource.GetType().GetMethod("TrySetCanceled"); + return (bool)trySetCanceled.Invoke(this.taskCompletionSource, null); + } + + public bool TrySetException(Exception ex) + { + var trySetException = taskCompletionSource.GetType() + .GetMethods() + .First(m => m.Name == "TrySetException" && m.GetParameters().First().ParameterType == typeof(IEnumerable)); + return (bool)trySetException.Invoke(this.taskCompletionSource, new[] { new[] { ex } }); + } + + public bool TrySetResult(object result) + { + var trySetResult = taskCompletionSource.GetType().GetMethod("TrySetResult"); + return (bool)trySetResult.Invoke(this.taskCompletionSource, new[] { result }); + } + + public Task Task + { + get + { + var taskProperty = taskCompletionSource.GetType().GetProperty("Task"); + return taskProperty.GetValue(this.taskCompletionSource) as Task; + } + } + } +} \ No newline at end of file diff --git a/Vendor/Prise.Proxy/runtime/DispatchProxy.cs b/Vendor/Prise.Proxy/runtime/DispatchProxy.cs new file mode 100644 index 0000000..40cd321 --- /dev/null +++ b/Vendor/Prise.Proxy/runtime/DispatchProxy.cs @@ -0,0 +1,38 @@ +namespace System.Reflection +{ + /// + /// DispatchProxy provides a mechanism for the instantiation of proxy objects and handling of + /// their method dispatch. + /// Original file: https://github.com/dotnet/runtime/blob/6072e4d3a7a2a1493f514cdf4be75a3d56580e84/src/libraries/System.Reflection.DispatchProxy/src/System/Reflection/DispatchProxy.cs + /// + public abstract class DispatchProxy + { + protected DispatchProxy() + { + } + + /// + /// Whenever any method on the generated proxy type is called, this method + /// will be invoked to dispatch control. + /// + /// The method the caller invoked + /// The arguments the caller passed to the method + /// The object to return to the caller, or null for void methods + protected abstract object? Invoke(MethodInfo? targetMethod, object?[]? args); + + /// + /// Creates an object instance that derives from class + /// and implements interface . + /// + /// The interface the proxy should implement. + /// The base class to use for the proxy class. + /// An object instance that implements . + /// is a class, + /// or is sealed or does not have a parameterless constructor + public static T Create() + where TProxy : DispatchProxy + { + return (T)DispatchProxyGenerator.CreateProxyInstance(typeof(TProxy), typeof(T)); + } + } +} \ No newline at end of file diff --git a/Vendor/Prise.Proxy/runtime/DispatchProxyGenerator.cs b/Vendor/Prise.Proxy/runtime/DispatchProxyGenerator.cs new file mode 100644 index 0000000..05e73a7 --- /dev/null +++ b/Vendor/Prise.Proxy/runtime/DispatchProxyGenerator.cs @@ -0,0 +1,935 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// Original file: https://github.com/dotnet/runtime/blob/6072e4d3a7a2a1493f514cdf4be75a3d56580e84/src/libraries/System.Reflection.DispatchProxy/src/System/Reflection/DispatchProxyGenerator.cs +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Reflection; +using System.Reflection.Emit; +using System.Runtime.ExceptionServices; +using System.Threading; + +namespace System.Reflection +{ + // Helper class to handle the IL EMIT for the generation of proxies. + // Much of this code was taken directly from the Silverlight proxy generation. + // Differences between this and the Silverlight version are: + // 1. This version is based on DispatchProxy from NET Native and CoreCLR, not RealProxy in Silverlight ServiceModel. + // There are several notable differences between them. + // 2. Both DispatchProxy and RealProxy permit the caller to ask for a proxy specifying a pair of types: + // the interface type to implement, and a base type. But they behave slightly differently: + // - RealProxy generates a proxy type that derives from Object and *implements" all the base type's + // interfaces plus all the interface type's interfaces. + // - DispatchProxy generates a proxy type that *derives* from the base type and implements all + // the interface type's interfaces. This is true for both the CLR version in NET Native and this + // version for CoreCLR. + // 3. DispatchProxy and RealProxy use different type hierarchies for the generated proxies: + // - RealProxy type hierarchy is: + // proxyType : proxyBaseType : object + // Presumably the 'proxyBaseType' in the middle is to allow it to implement the base type's interfaces + // explicitly, preventing collision for same name methods on the base and interface types. + // - DispatchProxy hierarchy is: + // proxyType : baseType (where baseType : DispatchProxy) + // The generated DispatchProxy proxy type does not need to generate implementation methods + // for the base type's interfaces, because the base type already must have implemented them. + // 4. RealProxy required a proxy instance to hold a backpointer to the RealProxy instance to mirror + // the .NET Remoting design that required the proxy and RealProxy to be separate instances. + // But the DispatchProxy design encourages the proxy type to *be* an DispatchProxy. Therefore, + // the proxy's 'this' becomes the equivalent of RealProxy's backpointer to RealProxy, so we were + // able to remove an extraneous field and ctor arg from the DispatchProxy proxies. + // + internal static class DispatchProxyGenerator + { + // Generated proxies have a private Action field that all generated methods + // invoke. It is the first field in the class and the first ctor parameter. + private const int InvokeActionFieldAndCtorParameterIndex = 0; + + // Proxies are requested for a pair of types: base type and interface type. + // The generated proxy will subclass the given base type and implement the interface type. + // We maintain a cache keyed by 'base type' containing a dictionary keyed by interface type, + // containing the generated proxy type for that pair. There are likely to be few (maybe only 1) + // base type in use for many interface types. + // Note: this differs from Silverlight's RealProxy implementation which keys strictly off the + // interface type. But this does not allow the same interface type to be used with more than a + // single base type. The implementation here permits multiple interface types to be used with + // multiple base types, and the generated proxy types will be unique. + // This cache of generated types grows unbounded, one element per unique T/ProxyT pair. + // This approach is used to prevent regenerating identical proxy types for identical T/Proxy pairs, + // which would ultimately be a more expensive leak. + // Proxy instances are not cached. Their lifetime is entirely owned by the caller of DispatchProxy.Create. + private static readonly Dictionary> s_baseTypeAndInterfaceToGeneratedProxyType = new Dictionary>(); + private static readonly ProxyAssembly s_proxyAssembly = new ProxyAssembly(); + private static readonly MethodInfo s_dispatchProxyInvokeMethod = typeof(DispatchProxy).GetTypeInfo().GetDeclaredMethod("Invoke")!; + + // Returns a new instance of a proxy the derives from 'baseType' and implements 'interfaceType' + internal static object CreateProxyInstance(Type baseType, Type interfaceType) + { + Debug.Assert(baseType != null); + Debug.Assert(interfaceType != null); + + Type proxiedType = GetProxyType(baseType!, interfaceType!); + return Activator.CreateInstance(proxiedType, (Action)DispatchProxyGenerator.Invoke)!; + } + + private static Type GetProxyType(Type baseType, Type interfaceType) + { + lock (s_baseTypeAndInterfaceToGeneratedProxyType) + { + if (!s_baseTypeAndInterfaceToGeneratedProxyType.TryGetValue(baseType, out Dictionary? interfaceToProxy)) + { + interfaceToProxy = new Dictionary(); + s_baseTypeAndInterfaceToGeneratedProxyType[baseType] = interfaceToProxy; + } + + if (!interfaceToProxy.TryGetValue(interfaceType, out Type? generatedProxy)) + { + generatedProxy = GenerateProxyType(baseType, interfaceType); + interfaceToProxy[interfaceType] = generatedProxy; + } + + return generatedProxy; + } + } + + // Unconditionally generates a new proxy type derived from 'baseType' and implements 'interfaceType' + private static Type GenerateProxyType(Type baseType, Type interfaceType) + { + // Parameter validation is deferred until the point we need to create the proxy. + // This prevents unnecessary overhead revalidating cached proxy types. + TypeInfo baseTypeInfo = baseType.GetTypeInfo(); + + // The interface type must be an interface, not a class + if (!interfaceType.GetTypeInfo().IsInterface) + { + // "T" is the generic parameter seen via the public contract + throw new ArgumentException("SR.Format(SR.InterfaceType_Must_Be_Interface, interfaceType.FullName)", "T"); + } + + // The base type cannot be sealed because the proxy needs to subclass it. + if (baseTypeInfo.IsSealed) + { + // "TProxy" is the generic parameter seen via the public contract + throw new ArgumentException("SR.Format(SR.BaseType_Cannot_Be_Sealed, baseTypeInfo.FullName)", "TProxy"); + } + + // The base type cannot be abstract + if (baseTypeInfo.IsAbstract) + { + throw new ArgumentException("SR.Format(SR.BaseType_Cannot_Be_Abstract, baseType.FullName)", "TProxy"); + } + + // The base type must have a public default ctor + if (!baseTypeInfo.DeclaredConstructors.Any(c => c.IsPublic && c.GetParameters().Length == 0)) + { + throw new ArgumentException("SR.Format(SR.BaseType_Must_Have_Default_Ctor, baseType.FullName)", "TProxy"); + } + + // Create a type that derives from 'baseType' provided by caller + ProxyBuilder pb = s_proxyAssembly.CreateProxy("generatedProxy", baseType); + + foreach (Type t in interfaceType.GetTypeInfo().ImplementedInterfaces) + pb.AddInterfaceImpl(t); + + pb.AddInterfaceImpl(interfaceType); + + Type generatedProxyType = pb.CreateType(); + return generatedProxyType; + } + + // All generated proxy methods call this static helper method to dispatch. + // Its job is to unpack the arguments and the 'this' instance and to dispatch directly + // to the (abstract) DispatchProxy.Invoke() method. + private static void Invoke(object?[] args) + { + PackedArgs packed = new PackedArgs(args); + MethodBase method = s_proxyAssembly.ResolveMethodToken(packed.DeclaringType, packed.MethodToken); + if (method.IsGenericMethodDefinition) + method = ((MethodInfo)method).MakeGenericMethod(packed.GenericTypes!); + + // Call (protected method) DispatchProxy.Invoke() + try + { + Debug.Assert(s_dispatchProxyInvokeMethod != null); + object? returnValue = s_dispatchProxyInvokeMethod!.Invoke(packed.DispatchProxy, + new object?[] { method, packed.Args }); + packed.ReturnValue = returnValue; + } + catch (TargetInvocationException tie) + { + Debug.Assert(tie.InnerException != null); + ExceptionDispatchInfo.Capture(tie.InnerException).Throw(); + } + } + + private class PackedArgs + { + internal const int DispatchProxyPosition = 0; + internal const int DeclaringTypePosition = 1; + internal const int MethodTokenPosition = 2; + internal const int ArgsPosition = 3; + internal const int GenericTypesPosition = 4; + internal const int ReturnValuePosition = 5; + + internal static readonly Type[] PackedTypes = new Type[] { typeof(object), typeof(Type), typeof(int), typeof(object[]), typeof(Type[]), typeof(object) }; + + private readonly object?[] _args; + internal PackedArgs() : this(new object[PackedTypes.Length]) { } + internal PackedArgs(object?[] args) { _args = args; } + + internal DispatchProxy? DispatchProxy { get { return (DispatchProxy?)_args[DispatchProxyPosition]; } } + internal Type? DeclaringType { get { return (Type?)_args[DeclaringTypePosition]; } } + internal int MethodToken { get { return (int)_args[MethodTokenPosition]!; } } + internal object[]? Args { get { return (object[]?)_args[ArgsPosition]; } } + internal Type[]? GenericTypes { get { return (Type[]?)_args[GenericTypesPosition]; } } + internal object? ReturnValue { /*get { return args[ReturnValuePosition]; }*/ set { _args[ReturnValuePosition] = value; } } + } + + private class ProxyAssembly + { + private readonly AssemblyBuilder _ab; + private readonly ModuleBuilder _mb; + private int _typeId; + + // Maintain a MethodBase-->int, int-->MethodBase mapping to permit generated code + // to pass methods by token + private readonly Dictionary _methodToToken = new Dictionary(); + private readonly List _methodsByToken = new List(); + private readonly HashSet _ignoresAccessAssemblyNames = new HashSet(); + private ConstructorInfo? _ignoresAccessChecksToAttributeConstructor; + + public ProxyAssembly() + { + _ab = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName("ProxyBuilder"), AssemblyBuilderAccess.Run); + _mb = _ab.DefineDynamicModule("testmod"); + } + + // Gets or creates the ConstructorInfo for the IgnoresAccessChecksAttribute. + // This attribute is both defined and referenced in the dynamic assembly to + // allow access to internal types in other assemblies. + internal ConstructorInfo IgnoresAccessChecksAttributeConstructor + { + get + { + if (_ignoresAccessChecksToAttributeConstructor == null) + { + _ignoresAccessChecksToAttributeConstructor = IgnoreAccessChecksToAttributeBuilder.AddToModule(_mb); + } + + return null; + } + } + public ProxyBuilder CreateProxy(string name, Type proxyBaseType) + { + int nextId = Interlocked.Increment(ref _typeId); + TypeBuilder tb = _mb.DefineType(name + "_" + nextId, TypeAttributes.Public, proxyBaseType); + return new ProxyBuilder(this, tb, proxyBaseType); + } + + // Generates an instance of the IgnoresAccessChecksToAttribute to + // identify the given assembly as one which contains internal types + // the dynamic assembly will need to reference. + internal void GenerateInstanceOfIgnoresAccessChecksToAttribute(string assemblyName) + { + // Add this assembly level attribute: + // [assembly: System.Runtime.CompilerServices.IgnoresAccessChecksToAttribute(assemblyName)] + ConstructorInfo attributeConstructor = IgnoresAccessChecksAttributeConstructor; + CustomAttributeBuilder customAttributeBuilder = + new CustomAttributeBuilder(attributeConstructor, new object[] { assemblyName }); + _ab.SetCustomAttribute(customAttributeBuilder); + } + + // Ensures the type we will reference from the dynamic assembly + // is visible. Non-public types need to emit an attribute that + // allows access from the dynamic assembly. + internal void EnsureTypeIsVisible(Type type) + { + TypeInfo typeInfo = type.GetTypeInfo(); + if (!typeInfo.IsVisible) + { + string assemblyName = typeInfo.Assembly.GetName().Name!; + if (!_ignoresAccessAssemblyNames.Contains(assemblyName)) + { + GenerateInstanceOfIgnoresAccessChecksToAttribute(assemblyName); + _ignoresAccessAssemblyNames.Add(assemblyName); + } + } + } + + internal void GetTokenForMethod(MethodBase method, out Type type, out int token) + { + Debug.Assert(method.DeclaringType != null); + type = method.DeclaringType!; + token = 0; + if (!_methodToToken.TryGetValue(method, out token)) + { + _methodsByToken.Add(method); + token = _methodsByToken.Count - 1; + _methodToToken[method] = token; + } + } + + internal MethodBase ResolveMethodToken(Type? type, int token) + { + Debug.Assert(token >= 0 && token < _methodsByToken.Count); + return _methodsByToken[token]; + } + } + + private class ProxyBuilder + { + private static readonly MethodInfo s_delegateInvoke = typeof(Action).GetTypeInfo().GetDeclaredMethod("Invoke")!; + + private readonly ProxyAssembly _assembly; + private readonly TypeBuilder _tb; + private readonly Type _proxyBaseType; + private readonly List _fields; + + internal ProxyBuilder(ProxyAssembly assembly, TypeBuilder tb, Type proxyBaseType) + { + _assembly = assembly; + _tb = tb; + _proxyBaseType = proxyBaseType; + + _fields = new List(); + _fields.Add(tb.DefineField("invoke", typeof(Action), FieldAttributes.Private)); + } + + private void Complete() + { + Type[] args = new Type[_fields.Count]; + for (int i = 0; i < args.Length; i++) + { + args[i] = _fields[i].FieldType; + } + + ConstructorBuilder cb = _tb.DefineConstructor(MethodAttributes.Public, CallingConventions.HasThis, args); + ILGenerator il = cb.GetILGenerator(); + + // chained ctor call + ConstructorInfo? baseCtor = _proxyBaseType.GetTypeInfo().DeclaredConstructors.SingleOrDefault(c => c.IsPublic && c.GetParameters().Length == 0); + Debug.Assert(baseCtor != null); + + il.Emit(OpCodes.Ldarg_0); + il.Emit(OpCodes.Call, baseCtor!); + + // store all the fields + for (int i = 0; i < args.Length; i++) + { + il.Emit(OpCodes.Ldarg_0); + il.Emit(OpCodes.Ldarg, i + 1); + il.Emit(OpCodes.Stfld, _fields[i]); + } + + il.Emit(OpCodes.Ret); + } + + internal Type CreateType() + { + this.Complete(); + return _tb.CreateTypeInfo()!.AsType(); + } + + internal void AddInterfaceImpl(Type iface) + { + // If necessary, generate an attribute to permit visibility + // to internal types. + _assembly.EnsureTypeIsVisible(iface); + + _tb.AddInterfaceImplementation(iface); + + // AccessorMethods -> Metadata mappings. + var propertyMap = new Dictionary(MethodInfoEqualityComparer.Instance); + foreach (PropertyInfo pi in iface.GetRuntimeProperties()) + { + var ai = new PropertyAccessorInfo(pi.GetMethod, pi.SetMethod); + if (pi.GetMethod != null) + propertyMap[pi.GetMethod] = ai; + if (pi.SetMethod != null) + propertyMap[pi.SetMethod] = ai; + } + + var eventMap = new Dictionary(MethodInfoEqualityComparer.Instance); + foreach (EventInfo ei in iface.GetRuntimeEvents()) + { + var ai = new EventAccessorInfo(ei.AddMethod, ei.RemoveMethod, ei.RaiseMethod); + if (ei.AddMethod != null) + eventMap[ei.AddMethod] = ai; + if (ei.RemoveMethod != null) + eventMap[ei.RemoveMethod] = ai; + if (ei.RaiseMethod != null) + eventMap[ei.RaiseMethod] = ai; + } + + foreach (MethodInfo mi in iface.GetRuntimeMethods()) + { + // Skip regular/non-virtual instance methods, static methods, and methods that cannot be overriden + // ("methods that cannot be overriden" includes default implementation of other interface methods). + if (!mi.IsVirtual || mi.IsFinal) + continue; + + MethodBuilder mdb = AddMethodImpl(mi); + if (propertyMap.TryGetValue(mi, out PropertyAccessorInfo? associatedProperty)) + { + if (MethodInfoEqualityComparer.Instance.Equals(associatedProperty.InterfaceGetMethod, mi)) + associatedProperty.GetMethodBuilder = mdb; + else + associatedProperty.SetMethodBuilder = mdb; + } + + if (eventMap.TryGetValue(mi, out EventAccessorInfo? associatedEvent)) + { + if (MethodInfoEqualityComparer.Instance.Equals(associatedEvent.InterfaceAddMethod, mi)) + associatedEvent.AddMethodBuilder = mdb; + else if (MethodInfoEqualityComparer.Instance.Equals(associatedEvent.InterfaceRemoveMethod, mi)) + associatedEvent.RemoveMethodBuilder = mdb; + else + associatedEvent.RaiseMethodBuilder = mdb; + } + } + + foreach (PropertyInfo pi in iface.GetRuntimeProperties()) + { + PropertyAccessorInfo ai = propertyMap[pi.GetMethod ?? pi.SetMethod!]; + + // If we didn't make an overriden accessor above, this was a static property, non-virtual property, + // or a default implementation of a property of a different interface. In any case, we don't need + // to redeclare it. + if (ai.GetMethodBuilder == null && ai.SetMethodBuilder == null) + continue; + + PropertyBuilder pb = _tb.DefineProperty(pi.Name, pi.Attributes, pi.PropertyType, pi.GetIndexParameters().Select(p => p.ParameterType).ToArray()); + if (ai.GetMethodBuilder != null) + pb.SetGetMethod(ai.GetMethodBuilder); + if (ai.SetMethodBuilder != null) + pb.SetSetMethod(ai.SetMethodBuilder); + } + + foreach (EventInfo ei in iface.GetRuntimeEvents()) + { + EventAccessorInfo ai = eventMap[ei.AddMethod ?? ei.RemoveMethod!]; + + // If we didn't make an overriden accessor above, this was a static event, non-virtual event, + // or a default implementation of an event of a different interface. In any case, we don't + // need to redeclare it. + if (ai.AddMethodBuilder == null && ai.RemoveMethodBuilder == null && ai.RaiseMethodBuilder == null) + continue; + + Debug.Assert(ei.EventHandlerType != null); + EventBuilder eb = _tb.DefineEvent(ei.Name, ei.Attributes, ei.EventHandlerType!); + if (ai.AddMethodBuilder != null) + eb.SetAddOnMethod(ai.AddMethodBuilder); + if (ai.RemoveMethodBuilder != null) + eb.SetRemoveOnMethod(ai.RemoveMethodBuilder); + if (ai.RaiseMethodBuilder != null) + eb.SetRaiseMethod(ai.RaiseMethodBuilder); + } + } + + private MethodBuilder AddMethodImpl(MethodInfo mi) + { + ParameterInfo[] parameters = mi.GetParameters(); + Type[] paramTypes = ParamTypes(parameters, false); + + MethodBuilder mdb = _tb.DefineMethod(mi.Name, MethodAttributes.Public | MethodAttributes.Virtual, mi.ReturnType, paramTypes); + if (mi.ContainsGenericParameters) + { + Type[] ts = mi.GetGenericArguments(); + string[] ss = new string[ts.Length]; + for (int i = 0; i < ts.Length; i++) + { + ss[i] = ts[i].Name; + } + GenericTypeParameterBuilder[] genericParameters = mdb.DefineGenericParameters(ss); + for (int i = 0; i < genericParameters.Length; i++) + { + genericParameters[i].SetGenericParameterAttributes(ts[i].GetTypeInfo().GenericParameterAttributes); + } + } + ILGenerator il = mdb.GetILGenerator(); + + ParametersArray args = new ParametersArray(il, paramTypes); + + // object[] args = new object[paramCount]; + il.Emit(OpCodes.Nop); + GenericArray argsArr = new GenericArray(il, ParamTypes(parameters, true).Length); + + for (int i = 0; i < parameters.Length; i++) + { + // args[i] = argi; + bool isOutRef = parameters[i].IsOut && parameters[i].ParameterType.IsByRef && !parameters[i].IsIn; + + if (!isOutRef) + { + argsArr.BeginSet(i); + args.Get(i); + argsArr.EndSet(parameters[i].ParameterType); + } + } + + // object[] packed = new object[PackedArgs.PackedTypes.Length]; + GenericArray packedArr = new GenericArray(il, PackedArgs.PackedTypes.Length); + + // packed[PackedArgs.DispatchProxyPosition] = this; + packedArr.BeginSet(PackedArgs.DispatchProxyPosition); + il.Emit(OpCodes.Ldarg_0); + packedArr.EndSet(typeof(DispatchProxy)); + + // packed[PackedArgs.DeclaringTypePosition] = typeof(iface); + MethodInfo Type_GetTypeFromHandle = typeof(Type).GetRuntimeMethod("GetTypeFromHandle", new Type[] { typeof(RuntimeTypeHandle) })!; + _assembly.GetTokenForMethod(mi, out Type declaringType, out int methodToken); + packedArr.BeginSet(PackedArgs.DeclaringTypePosition); + il.Emit(OpCodes.Ldtoken, declaringType); + il.Emit(OpCodes.Call, Type_GetTypeFromHandle); + packedArr.EndSet(typeof(object)); + + // packed[PackedArgs.MethodTokenPosition] = iface method token; + packedArr.BeginSet(PackedArgs.MethodTokenPosition); + il.Emit(OpCodes.Ldc_I4, methodToken); + packedArr.EndSet(typeof(int)); + + // packed[PackedArgs.ArgsPosition] = args; + packedArr.BeginSet(PackedArgs.ArgsPosition); + argsArr.Load(); + packedArr.EndSet(typeof(object[])); + + // packed[PackedArgs.GenericTypesPosition] = mi.GetGenericArguments(); + if (mi.ContainsGenericParameters) + { + packedArr.BeginSet(PackedArgs.GenericTypesPosition); + Type[] genericTypes = mi.GetGenericArguments(); + GenericArray typeArr = new GenericArray(il, genericTypes.Length); + for (int i = 0; i < genericTypes.Length; ++i) + { + typeArr.BeginSet(i); + il.Emit(OpCodes.Ldtoken, genericTypes[i]); + il.Emit(OpCodes.Call, Type_GetTypeFromHandle); + typeArr.EndSet(typeof(Type)); + } + typeArr.Load(); + packedArr.EndSet(typeof(Type[])); + } + + // Call static DispatchProxyHelper.Invoke(object[]) + il.Emit(OpCodes.Ldarg_0); + il.Emit(OpCodes.Ldfld, _fields[InvokeActionFieldAndCtorParameterIndex]); // delegate + packedArr.Load(); + il.Emit(OpCodes.Call, s_delegateInvoke); + + for (int i = 0; i < parameters.Length; i++) + { + if (parameters[i].ParameterType.IsByRef) + { + args.BeginSet(i); + argsArr.Get(i); + args.EndSet(i, typeof(object)); + } + } + + if (mi.ReturnType != typeof(void)) + { + packedArr.Get(PackedArgs.ReturnValuePosition); + Convert(il, typeof(object), mi.ReturnType, false); + } + + il.Emit(OpCodes.Ret); + + _tb.DefineMethodOverride(mdb, mi); + return mdb; + } + + private static Type[] ParamTypes(ParameterInfo[] parms, bool noByRef) + { + Type[] types = new Type[parms.Length]; + for (int i = 0; i < parms.Length; i++) + { + types[i] = parms[i].ParameterType; + if (noByRef && types[i].IsByRef) + types[i] = types[i].GetElementType()!; + } + return types; + } + + // TypeCode does not exist in ProjectK or ProjectN. + // This lookup method was copied from PortableLibraryThunks\Internal\PortableLibraryThunks\System\TypeThunks.cs + // but returns the integer value equivalent to its TypeCode enum. + private static int GetTypeCode(Type? type) + { + if (type == null) + return 0; // TypeCode.Empty; + + if (type == typeof(bool)) + return 3; // TypeCode.Boolean; + + if (type == typeof(char)) + return 4; // TypeCode.Char; + + if (type == typeof(sbyte)) + return 5; // TypeCode.SByte; + + if (type == typeof(byte)) + return 6; // TypeCode.Byte; + + if (type == typeof(short)) + return 7; // TypeCode.Int16; + + if (type == typeof(ushort)) + return 8; // TypeCode.UInt16; + + if (type == typeof(int)) + return 9; // TypeCode.Int32; + + if (type == typeof(uint)) + return 10; // TypeCode.UInt32; + + if (type == typeof(long)) + return 11; // TypeCode.Int64; + + if (type == typeof(ulong)) + return 12; // TypeCode.UInt64; + + if (type == typeof(float)) + return 13; // TypeCode.Single; + + if (type == typeof(double)) + return 14; // TypeCode.Double; + + if (type == typeof(decimal)) + return 15; // TypeCode.Decimal; + + if (type == typeof(DateTime)) + return 16; // TypeCode.DateTime; + + if (type == typeof(string)) + return 18; // TypeCode.String; + + if (type.GetTypeInfo().IsEnum) + return GetTypeCode(Enum.GetUnderlyingType(type)); + + return 1; // TypeCode.Object; + } + + private static readonly OpCode[] s_convOpCodes = new OpCode[] { + OpCodes.Nop, //Empty = 0, + OpCodes.Nop, //Object = 1, + OpCodes.Nop, //DBNull = 2, + OpCodes.Conv_I1, //Boolean = 3, + OpCodes.Conv_I2, //Char = 4, + OpCodes.Conv_I1, //SByte = 5, + OpCodes.Conv_U1, //Byte = 6, + OpCodes.Conv_I2, //Int16 = 7, + OpCodes.Conv_U2, //UInt16 = 8, + OpCodes.Conv_I4, //Int32 = 9, + OpCodes.Conv_U4, //UInt32 = 10, + OpCodes.Conv_I8, //Int64 = 11, + OpCodes.Conv_U8, //UInt64 = 12, + OpCodes.Conv_R4, //Single = 13, + OpCodes.Conv_R8, //Double = 14, + OpCodes.Nop, //Decimal = 15, + OpCodes.Nop, //DateTime = 16, + OpCodes.Nop, //17 + OpCodes.Nop, //String = 18, + }; + + private static readonly OpCode[] s_ldindOpCodes = new OpCode[] { + OpCodes.Nop, //Empty = 0, + OpCodes.Nop, //Object = 1, + OpCodes.Nop, //DBNull = 2, + OpCodes.Ldind_I1, //Boolean = 3, + OpCodes.Ldind_I2, //Char = 4, + OpCodes.Ldind_I1, //SByte = 5, + OpCodes.Ldind_U1, //Byte = 6, + OpCodes.Ldind_I2, //Int16 = 7, + OpCodes.Ldind_U2, //UInt16 = 8, + OpCodes.Ldind_I4, //Int32 = 9, + OpCodes.Ldind_U4, //UInt32 = 10, + OpCodes.Ldind_I8, //Int64 = 11, + OpCodes.Ldind_I8, //UInt64 = 12, + OpCodes.Ldind_R4, //Single = 13, + OpCodes.Ldind_R8, //Double = 14, + OpCodes.Nop, //Decimal = 15, + OpCodes.Nop, //DateTime = 16, + OpCodes.Nop, //17 + OpCodes.Ldind_Ref, //String = 18, + }; + + private static readonly OpCode[] s_stindOpCodes = new OpCode[] { + OpCodes.Nop, //Empty = 0, + OpCodes.Nop, //Object = 1, + OpCodes.Nop, //DBNull = 2, + OpCodes.Stind_I1, //Boolean = 3, + OpCodes.Stind_I2, //Char = 4, + OpCodes.Stind_I1, //SByte = 5, + OpCodes.Stind_I1, //Byte = 6, + OpCodes.Stind_I2, //Int16 = 7, + OpCodes.Stind_I2, //UInt16 = 8, + OpCodes.Stind_I4, //Int32 = 9, + OpCodes.Stind_I4, //UInt32 = 10, + OpCodes.Stind_I8, //Int64 = 11, + OpCodes.Stind_I8, //UInt64 = 12, + OpCodes.Stind_R4, //Single = 13, + OpCodes.Stind_R8, //Double = 14, + OpCodes.Nop, //Decimal = 15, + OpCodes.Nop, //DateTime = 16, + OpCodes.Nop, //17 + OpCodes.Stind_Ref, //String = 18, + }; + + private static void Convert(ILGenerator il, Type source, Type target, bool isAddress) + { + Debug.Assert(!target.IsByRef); + if (target == source) + return; + + TypeInfo sourceTypeInfo = source.GetTypeInfo(); + TypeInfo targetTypeInfo = target.GetTypeInfo(); + + if (source.IsByRef) + { + Debug.Assert(!isAddress); + Type argType = source.GetElementType()!; + Ldind(il, argType); + Convert(il, argType, target, isAddress); + return; + } + if (targetTypeInfo.IsValueType) + { + if (sourceTypeInfo.IsValueType) + { + OpCode opCode = s_convOpCodes[GetTypeCode(target)]; + Debug.Assert(!opCode.Equals(OpCodes.Nop)); + il.Emit(opCode); + } + else + { + Debug.Assert(sourceTypeInfo.IsAssignableFrom(targetTypeInfo)); + il.Emit(OpCodes.Unbox, target); + if (!isAddress) + Ldind(il, target); + } + } + else if (targetTypeInfo.IsAssignableFrom(sourceTypeInfo)) + { + if (sourceTypeInfo.IsValueType || source.IsGenericParameter) + { + if (isAddress) + Ldind(il, source); + il.Emit(OpCodes.Box, source); + } + } + else + { + Debug.Assert(sourceTypeInfo.IsAssignableFrom(targetTypeInfo) || targetTypeInfo.IsInterface || sourceTypeInfo.IsInterface); + if (target.IsGenericParameter) + { + il.Emit(OpCodes.Unbox_Any, target); + } + else + { + il.Emit(OpCodes.Castclass, target); + } + } + } + + private static void Ldind(ILGenerator il, Type type) + { + OpCode opCode = s_ldindOpCodes[GetTypeCode(type)]; + if (!opCode.Equals(OpCodes.Nop)) + { + il.Emit(opCode); + } + else + { + il.Emit(OpCodes.Ldobj, type); + } + } + + private static void Stind(ILGenerator il, Type type) + { + OpCode opCode = s_stindOpCodes[GetTypeCode(type)]; + if (!opCode.Equals(OpCodes.Nop)) + { + il.Emit(opCode); + } + else + { + il.Emit(OpCodes.Stobj, type); + } + } + + private class ParametersArray + { + private readonly ILGenerator _il; + private readonly Type[] _paramTypes; + internal ParametersArray(ILGenerator il, Type[] paramTypes) + { + _il = il; + _paramTypes = paramTypes; + } + + internal void Get(int i) + { + _il.Emit(OpCodes.Ldarg, i + 1); + } + + internal void BeginSet(int i) + { + _il.Emit(OpCodes.Ldarg, i + 1); + } + + internal void EndSet(int i, Type stackType) + { + Debug.Assert(_paramTypes[i].IsByRef); + Type argType = _paramTypes[i].GetElementType()!; + Convert(_il, stackType, argType, false); + Stind(_il, argType); + } + } + + private class GenericArray + { + private readonly ILGenerator _il; + private readonly LocalBuilder _lb; + internal GenericArray(ILGenerator il, int len) + { + _il = il; + _lb = il.DeclareLocal(typeof(T[])); + + il.Emit(OpCodes.Ldc_I4, len); + il.Emit(OpCodes.Newarr, typeof(T)); + il.Emit(OpCodes.Stloc, _lb); + } + + internal void Load() + { + _il.Emit(OpCodes.Ldloc, _lb); + } + + internal void Get(int i) + { + _il.Emit(OpCodes.Ldloc, _lb); + _il.Emit(OpCodes.Ldc_I4, i); + _il.Emit(OpCodes.Ldelem_Ref); + } + + internal void BeginSet(int i) + { + _il.Emit(OpCodes.Ldloc, _lb); + _il.Emit(OpCodes.Ldc_I4, i); + } + + internal void EndSet(Type stackType) + { + Convert(_il, stackType, typeof(T), false); + _il.Emit(OpCodes.Stelem_Ref); + } + } + + private sealed class PropertyAccessorInfo + { + public MethodInfo? InterfaceGetMethod { get; } + public MethodInfo? InterfaceSetMethod { get; } + public MethodBuilder? GetMethodBuilder { get; set; } + public MethodBuilder? SetMethodBuilder { get; set; } + + public PropertyAccessorInfo(MethodInfo? interfaceGetMethod, MethodInfo? interfaceSetMethod) + { + InterfaceGetMethod = interfaceGetMethod; + InterfaceSetMethod = interfaceSetMethod; + } + } + + private sealed class EventAccessorInfo + { + public MethodInfo? InterfaceAddMethod { get; } + public MethodInfo? InterfaceRemoveMethod { get; } + public MethodInfo? InterfaceRaiseMethod { get; } + public MethodBuilder? AddMethodBuilder { get; set; } + public MethodBuilder? RemoveMethodBuilder { get; set; } + public MethodBuilder? RaiseMethodBuilder { get; set; } + + public EventAccessorInfo(MethodInfo? interfaceAddMethod, MethodInfo? interfaceRemoveMethod, MethodInfo? interfaceRaiseMethod) + { + InterfaceAddMethod = interfaceAddMethod; + InterfaceRemoveMethod = interfaceRemoveMethod; + InterfaceRaiseMethod = interfaceRaiseMethod; + } + } + + private sealed class MethodInfoEqualityComparer : EqualityComparer + { + public static readonly MethodInfoEqualityComparer Instance = new MethodInfoEqualityComparer(); + + private MethodInfoEqualityComparer() { } + + public sealed override bool Equals(MethodInfo? left, MethodInfo? right) + { + if (ReferenceEquals(left, right)) + return true; + + if (left == null) + return right == null; + else if (right == null) + return false; + + // This assembly should work in netstandard1.3, + // so we cannot use MemberInfo.MetadataToken here. + // Therefore, it compares honestly referring ECMA-335 I.8.6.1.6 Signature Matching. + if (!Equals(left.DeclaringType, right.DeclaringType)) + return false; + + if (!Equals(left.ReturnType, right.ReturnType)) + return false; + + if (left.CallingConvention != right.CallingConvention) + return false; + + if (left.IsStatic != right.IsStatic) + return false; + + if (left.Name != right.Name) + return false; + + Type[] leftGenericParameters = left.GetGenericArguments(); + Type[] rightGenericParameters = right.GetGenericArguments(); + if (leftGenericParameters.Length != rightGenericParameters.Length) + return false; + + for (int i = 0; i < leftGenericParameters.Length; i++) + { + if (!Equals(leftGenericParameters[i], rightGenericParameters[i])) + return false; + } + + ParameterInfo[] leftParameters = left.GetParameters(); + ParameterInfo[] rightParameters = right.GetParameters(); + if (leftParameters.Length != rightParameters.Length) + return false; + + for (int i = 0; i < leftParameters.Length; i++) + { + if (!Equals(leftParameters[i].ParameterType, rightParameters[i].ParameterType)) + return false; + } + + return true; + } + + public sealed override int GetHashCode(MethodInfo obj) + { + if (obj == null) + return 0; + + Debug.Assert(obj.DeclaringType != null); + int hashCode = obj.DeclaringType!.GetHashCode(); + hashCode ^= obj.Name.GetHashCode(); + foreach (ParameterInfo parameter in obj.GetParameters()) + { + hashCode ^= parameter.ParameterType.GetHashCode(); + } + + return hashCode; + } + } + } + } +} \ No newline at end of file diff --git a/Vendor/Prise.Proxy/runtime/IngoreAccessChecksToAttributeBuilder.cs b/Vendor/Prise.Proxy/runtime/IngoreAccessChecksToAttributeBuilder.cs new file mode 100644 index 0000000..9d1c3a4 --- /dev/null +++ b/Vendor/Prise.Proxy/runtime/IngoreAccessChecksToAttributeBuilder.cs @@ -0,0 +1,101 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. +// Original File: https://github.com/dotnet/runtime/blob/6072e4d3a7a2a1493f514cdf4be75a3d56580e84/src/libraries/Common/src/System/Reflection/Emit/IgnoreAccessChecksToAttributeBuilder.cs +using System.Linq; + +namespace System.Reflection.Emit +{ + internal static class IgnoreAccessChecksToAttributeBuilder + { + /// + /// Generate the declaration for the IgnoresAccessChecksToAttribute type. + /// This attribute will be both defined and used in the dynamic assembly. + /// Each usage identifies the name of the assembly containing non-public + /// types the dynamic assembly needs to access. Normally those types + /// would be inaccessible, but this attribute allows them to be visible. + /// It works like a reverse InternalsVisibleToAttribute. + /// This method returns the ConstructorInfo of the generated attribute. + /// + public static ConstructorInfo AddToModule(ModuleBuilder mb) + { + TypeBuilder attributeTypeBuilder = + mb.DefineType("System.Runtime.CompilerServices.IgnoresAccessChecksToAttribute", + TypeAttributes.Public | TypeAttributes.Class, + typeof(Attribute)); + + // Create backing field as: + // private string assemblyName; + FieldBuilder assemblyNameField = + attributeTypeBuilder.DefineField("assemblyName", typeof(string), FieldAttributes.Private); + + // Create ctor as: + // public IgnoresAccessChecksToAttribute(string) + ConstructorBuilder constructorBuilder = attributeTypeBuilder.DefineConstructor(MethodAttributes.Public, + CallingConventions.HasThis, + new Type[] { assemblyNameField.FieldType }); + + ILGenerator il = constructorBuilder.GetILGenerator(); + + // Create ctor body as: + // this.assemblyName = {ctor parameter 0} + il.Emit(OpCodes.Ldarg_0); + il.Emit(OpCodes.Ldarg, 1); + il.Emit(OpCodes.Stfld, assemblyNameField); + + // return + il.Emit(OpCodes.Ret); + + // Define property as: + // public string AssemblyName {get { return this.assemblyName; } } + _ = attributeTypeBuilder.DefineProperty( + "AssemblyName", + PropertyAttributes.None, + CallingConventions.HasThis, + returnType: typeof(string), + parameterTypes: null); + + MethodBuilder getterMethodBuilder = attributeTypeBuilder.DefineMethod( + "get_AssemblyName", + MethodAttributes.Public, + CallingConventions.HasThis, + returnType: typeof(string), + parameterTypes: null); + + // Generate body: + // return this.assemblyName; + il = getterMethodBuilder.GetILGenerator(); + il.Emit(OpCodes.Ldarg_0); + il.Emit(OpCodes.Ldfld, assemblyNameField); + il.Emit(OpCodes.Ret); + + // Generate the AttributeUsage attribute for this attribute type: + // [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] + TypeInfo attributeUsageTypeInfo = typeof(AttributeUsageAttribute).GetTypeInfo(); + + // Find the ctor that takes only AttributeTargets + ConstructorInfo attributeUsageConstructorInfo = + attributeUsageTypeInfo.DeclaredConstructors + .Single(c => c.GetParameters().Length == 1 && + c.GetParameters()[0].ParameterType == typeof(AttributeTargets)); + + // Find the property to set AllowMultiple + PropertyInfo allowMultipleProperty = + attributeUsageTypeInfo.DeclaredProperties + .Single(f => string.Equals(f.Name, "AllowMultiple")); + + // Create a builder to construct the instance via the ctor and property + CustomAttributeBuilder customAttributeBuilder = + new CustomAttributeBuilder(attributeUsageConstructorInfo, + new object[] { AttributeTargets.Assembly }, + new PropertyInfo[] { allowMultipleProperty }, + new object[] { true }); + + // Attach this attribute instance to the newly defined attribute type + attributeTypeBuilder.SetCustomAttribute(customAttributeBuilder); + + // Make the TypeInfo real so the constructor can be used. + return attributeTypeBuilder.CreateTypeInfo()!.DeclaredConstructors.Single(); + } + } +} diff --git a/Vendor/Prise.ReverseProxy/Prise.ReverseProxy.csproj b/Vendor/Prise.ReverseProxy/Prise.ReverseProxy.csproj new file mode 100644 index 0000000..b8e3d16 --- /dev/null +++ b/Vendor/Prise.ReverseProxy/Prise.ReverseProxy.csproj @@ -0,0 +1,61 @@ + + + + net9.0 + Prise.ReverseProxy + Prise.ReverseProxy + Adds support for sharing services between a Prise Host and a Prise Plugin + Maarten Merken + MRKN + plugin;framework;prise;decoupling;assembly;dispatchproxy;proxy + $(TargetsForTfmSpecificBuildOutput);CopyProjectReferencesToPackage + enable + default + https://raw.githubusercontent.com/merken/Prise/master/LICENSE + https://github.com/merken/Prise + https://github.com/merken/Prise.git + git + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + icon.png + + + + + True + + + + + diff --git a/Vendor/Prise.ReverseProxy/ReverseProxy.cs b/Vendor/Prise.ReverseProxy/ReverseProxy.cs new file mode 100644 index 0000000..ed1bc7d --- /dev/null +++ b/Vendor/Prise.ReverseProxy/ReverseProxy.cs @@ -0,0 +1,53 @@ +using System.Diagnostics; +using System.Linq; +using System.Reflection; +using Prise.Infrastructure; + +namespace Prise.Proxy +{ + /// + /// The ReverseProxy is a base class that will provide a proxy to a Host Service from the Plugin (in reverse). + /// + public abstract class ReverseProxy + { + protected object hostService; + protected ReverseProxy(object hostService) + { + this.hostService = hostService; + } + + private MethodBase GetCallingMethod() => new StackTrace().GetFrame(2).GetMethod(); + + /// + /// This handles void proxy calls to the hostService + /// + /// The list of method parameters + protected void InvokeOnHostService(params object[] parameters) + { + var callingMethod = GetCallingMethod(); + var methodInfo = PriseProxy.FindMethodOnObject(callingMethod as MethodInfo, this); + if (methodInfo.GetParameters().Count() != parameters.Count()) + throw new ReverseProxyException($"The number of parameters provided to this ReverseProxy {parameters?.Count()} do not match the actual parameter count of the hostService method ({methodInfo.GetParameters().Count()}). Did you forget to provide the correct number of parameters?"); + + this.Invoke(hostService, methodInfo, parameters ?? new object[] { }); + } + + /// + /// This handles proxy calls to the hostService + /// + /// The list of method parameters + /// Return reference type of the calling method + /// The response of the invocation on the host object + protected T InvokeOnHostService(params object[] parameters) + { + var callingMethod = GetCallingMethod(); + var methodInfo = PriseProxy.FindMethodOnObject(callingMethod as MethodInfo, this); + if (methodInfo.GetParameters().Count() != parameters.Count()) + throw new ReverseProxyException($"The number of parameters provided to this ReverseProxy {parameters?.Count()} do not match the actual parameter count of the hostService method ({methodInfo.GetParameters().Count()}). Did you forget to provide the correct number of parameters?"); + + return (T)this.Invoke(hostService, methodInfo, parameters ?? new object[] { }); + } + + private object Invoke(object hostService, MethodInfo methodInfo, object[] parameters) => PriseProxy.Invoke(hostService, methodInfo, parameters ?? new object[] { }, new JsonSerializerParameterConverter(), new JsonSerializerResultConverter()); + } +} \ No newline at end of file diff --git a/Vendor/Prise.ReverseProxy/ReverseProxyException.cs b/Vendor/Prise.ReverseProxy/ReverseProxyException.cs new file mode 100644 index 0000000..fa90225 --- /dev/null +++ b/Vendor/Prise.ReverseProxy/ReverseProxyException.cs @@ -0,0 +1,13 @@ +namespace Prise.Proxy +{ + [System.Serializable] + public class ReverseProxyException : System.Exception + { + public ReverseProxyException() { } + public ReverseProxyException(string message) : base(message) { } + public ReverseProxyException(string message, System.Exception inner) : base(message, inner) { } + protected ReverseProxyException( + System.Runtime.Serialization.SerializationInfo info, + System.Runtime.Serialization.StreamingContext context) : base(info, context) { } + } +} \ No newline at end of file diff --git a/Vendor/Prise.Testing/Prise.Testing.csproj b/Vendor/Prise.Testing/Prise.Testing.csproj new file mode 100644 index 0000000..fbd6174 --- /dev/null +++ b/Vendor/Prise.Testing/Prise.Testing.csproj @@ -0,0 +1,29 @@ + + + + netstandard2.0 + Prise.Testing + Prise.Testing + Testing support for your Prise Plugins! + Maarten Merken + MRKN + plugin;framework;prise;decoupling;assembly;dispatchproxy;proxy + + + + + + + + icon.png + true + + + + + True + + + + + diff --git a/Vendor/Prise.Testing/Testing.cs b/Vendor/Prise.Testing/Testing.cs new file mode 100644 index 0000000..aea8307 --- /dev/null +++ b/Vendor/Prise.Testing/Testing.cs @@ -0,0 +1,35 @@ +using System; +using System.Linq; +using System.Reflection; + +namespace Prise +{ + public static class Testing + { + public static T CreateTestPluginInstance(params object[] pluginServices) + { + var pluginType = typeof(T); + var pluginInstance = typeof(T).Assembly.CreateInstance(typeof(T).FullName); + var services = pluginType.GetTypeInfo().DeclaredFields.Where(f => f.CustomAttributes.Any(c => c.AttributeType.Name == typeof(Prise.Plugin.PluginServiceAttribute).Name)); + foreach (var service in services) + { + var serviceType = service.FieldType; + var pluginService = pluginServices.FirstOrDefault(p => serviceType.IsAssignableFrom(p.GetType())); + if (pluginService == null) + throw new ArgumentException($"A pluginService of type {serviceType.Name} is required for activating plugin {pluginType.Name}."); + + pluginInstance + .GetType() + .GetTypeInfo() + .DeclaredFields + .First(f => f.Name == service.Name) + .SetValue(pluginInstance, pluginService); + + var activationMethod = pluginType.GetMethods(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public).FirstOrDefault(m => m.CustomAttributes.Any(c => c.AttributeType.Name == typeof(Prise.Plugin.PluginActivatedAttribute).Name)); + activationMethod.Invoke(pluginInstance, null); + } + + return (T)pluginInstance; + } + } +} diff --git a/Vendor/Prise.Tests.Integration/.vscode/launch.json b/Vendor/Prise.Tests.Integration/.vscode/launch.json new file mode 100644 index 0000000..7a84fb8 --- /dev/null +++ b/Vendor/Prise.Tests.Integration/.vscode/launch.json @@ -0,0 +1,19 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "IntegrationTestHost", + "type": "coreclr", + "request": "launch", + "preLaunchTask": "build", + "program": "${workspaceFolder}/Prise.IntegrationTestsHost/bin/Debug/netcoreapp3.1/Prise.IntegrationTestsHost.dll", + "args": [], + "cwd": "${workspaceFolder}/Prise.IntegrationTestsHost", + "console": "externalTerminal", + "stopAtEntry": false + }, + ] +} \ No newline at end of file diff --git a/Vendor/Prise.Tests.Integration/.vscode/tasks.json b/Vendor/Prise.Tests.Integration/.vscode/tasks.json new file mode 100644 index 0000000..8c9e0a5 --- /dev/null +++ b/Vendor/Prise.Tests.Integration/.vscode/tasks.json @@ -0,0 +1,17 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "label": "build", + "command": "dotnet", + "type": "process", + "args": [ + "build", + "${workspaceFolder}/Prise.IntegrationTestsHost/Prise.IntegrationTestsHost.csproj", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary" + ], + "problemMatcher": "$msCompile" + } + ] +} \ No newline at end of file diff --git a/Vendor/Prise.Tests.Integration/FileBulkDateChanger/FileBulkDateChanger.deps.json b/Vendor/Prise.Tests.Integration/FileBulkDateChanger/FileBulkDateChanger.deps.json new file mode 100644 index 0000000..f54d6d3 --- /dev/null +++ b/Vendor/Prise.Tests.Integration/FileBulkDateChanger/FileBulkDateChanger.deps.json @@ -0,0 +1,23 @@ +{ + "runtimeTarget": { + "name": ".NETCoreApp,Version=v3.1", + "signature": "" + }, + "compilationOptions": {}, + "targets": { + ".NETCoreApp,Version=v3.1": { + "FileBulkDateChanger/1.0.0": { + "runtime": { + "FileBulkDateChanger.dll": {} + } + } + } + }, + "libraries": { + "FileBulkDateChanger/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + } + } +} \ No newline at end of file diff --git a/Vendor/Prise.Tests.Integration/FileBulkDateChanger/FileBulkDateChanger.dll b/Vendor/Prise.Tests.Integration/FileBulkDateChanger/FileBulkDateChanger.dll new file mode 100644 index 0000000..c1ffdd5 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/FileBulkDateChanger/FileBulkDateChanger.dll differ diff --git a/Vendor/Prise.Tests.Integration/FileBulkDateChanger/FileBulkDateChanger.exe b/Vendor/Prise.Tests.Integration/FileBulkDateChanger/FileBulkDateChanger.exe new file mode 100644 index 0000000..b5b11f4 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/FileBulkDateChanger/FileBulkDateChanger.exe differ diff --git a/Vendor/Prise.Tests.Integration/FileBulkDateChanger/FileBulkDateChanger.pdb b/Vendor/Prise.Tests.Integration/FileBulkDateChanger/FileBulkDateChanger.pdb new file mode 100644 index 0000000..1df1c42 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/FileBulkDateChanger/FileBulkDateChanger.pdb differ diff --git a/Vendor/Prise.Tests.Integration/FileBulkDateChanger/FileBulkDateChanger.runtimeconfig.dev.json b/Vendor/Prise.Tests.Integration/FileBulkDateChanger/FileBulkDateChanger.runtimeconfig.dev.json new file mode 100644 index 0000000..a8fe619 --- /dev/null +++ b/Vendor/Prise.Tests.Integration/FileBulkDateChanger/FileBulkDateChanger.runtimeconfig.dev.json @@ -0,0 +1,10 @@ +{ + "runtimeOptions": { + "additionalProbingPaths": [ + "C:\\Users\\alper\\.dotnet\\store\\|arch|\\|tfm|", + "C:\\Users\\alper\\.nuget\\packages", + "C:\\Microsoft\\Xamarin\\NuGet", + "C:\\Program Files\\dotnet\\sdk\\NuGetFallbackFolder" + ] + } +} \ No newline at end of file diff --git a/Vendor/Prise.Tests.Integration/FileBulkDateChanger/FileBulkDateChanger.runtimeconfig.json b/Vendor/Prise.Tests.Integration/FileBulkDateChanger/FileBulkDateChanger.runtimeconfig.json new file mode 100644 index 0000000..bc456d7 --- /dev/null +++ b/Vendor/Prise.Tests.Integration/FileBulkDateChanger/FileBulkDateChanger.runtimeconfig.json @@ -0,0 +1,9 @@ +{ + "runtimeOptions": { + "tfm": "netcoreapp3.1", + "framework": { + "name": "Microsoft.NETCore.App", + "version": "3.1.0" + } + } +} \ No newline at end of file diff --git a/Vendor/Prise.Tests.Integration/IntegrationTestsPlugins/DomainForPluginC/DomainForPluginC.csproj b/Vendor/Prise.Tests.Integration/IntegrationTestsPlugins/DomainForPluginC/DomainForPluginC.csproj new file mode 100644 index 0000000..9f5c4f4 --- /dev/null +++ b/Vendor/Prise.Tests.Integration/IntegrationTestsPlugins/DomainForPluginC/DomainForPluginC.csproj @@ -0,0 +1,7 @@ + + + + netstandard2.0 + + + diff --git a/Vendor/Prise.Tests.Integration/IntegrationTestsPlugins/DomainForPluginC/IDiscount.cs b/Vendor/Prise.Tests.Integration/IntegrationTestsPlugins/DomainForPluginC/IDiscount.cs new file mode 100644 index 0000000..3f80a60 --- /dev/null +++ b/Vendor/Prise.Tests.Integration/IntegrationTestsPlugins/DomainForPluginC/IDiscount.cs @@ -0,0 +1,18 @@ +namespace DomainForPluginC +{ + public interface IDiscount + { + decimal Amount { get; } + } + + public class Discount : IDiscount + { + private readonly decimal amount; + public Discount(decimal amount) + { + this.amount = amount; + } + + public decimal Amount => amount; + } +} \ No newline at end of file diff --git a/Vendor/Prise.Tests.Integration/IntegrationTestsPlugins/DomainForPluginC/IDiscountService.cs b/Vendor/Prise.Tests.Integration/IntegrationTestsPlugins/DomainForPluginC/IDiscountService.cs new file mode 100644 index 0000000..91df899 --- /dev/null +++ b/Vendor/Prise.Tests.Integration/IntegrationTestsPlugins/DomainForPluginC/IDiscountService.cs @@ -0,0 +1,23 @@ +using System; + +namespace DomainForPluginC +{ + public interface IDiscountService + { + decimal ApplyDiscount(decimal result); + } + + public class DiscountService : IDiscountService + { + private readonly IDiscount discount; + public DiscountService(IDiscount discount) + { + this.discount = discount; + + } + public decimal ApplyDiscount(decimal result) + { + return result * this.discount.Amount; + } + } +} \ No newline at end of file diff --git a/Vendor/Prise.Tests.Integration/IntegrationTestsPlugins/PluginA/AdditionCalculationPlugin.cs b/Vendor/Prise.Tests.Integration/IntegrationTestsPlugins/PluginA/AdditionCalculationPlugin.cs new file mode 100644 index 0000000..40b81b9 --- /dev/null +++ b/Vendor/Prise.Tests.Integration/IntegrationTestsPlugins/PluginA/AdditionCalculationPlugin.cs @@ -0,0 +1,64 @@ +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Prise.IntegrationTestsContract; +using Prise.Plugin; + +namespace PluginA +{ + /// + /// This plugin does not require any 3rd party dependencies or dependency injection, + /// as long as a default parameterless constructor is present (implicitly or explicitly), this plugin will get loaded. + /// + [Plugin(PluginType = typeof(ICalculationPlugin))] + public class AdditionCalculationPlugin : ICalculationPlugin + { + public string Name => nameof(AdditionCalculationPlugin); + public string Description => "This plugin performs addition"; + public int Calculate(int a, int b) + { + return a + b; + } + + public decimal Calculate(decimal a, decimal b) + { + return a + b; + } + + public decimal CalculateComplex(CalculationContext context) + { + return context.A + context.B; + } + + public CalculationResult CalculateComplexResult(CalculationContext context) + { + return new CalculationResult + { + Result = context.A + context.B + }; + } + + public ComplexCalculationResult CalculateMutiple(ComplexCalculationContext context) + { + var results = new List(); + results.AddRange(context.Calculations.Select(c => new CalculationResult { Result = c.A + c.B })); + return new ComplexCalculationResult + { + Results = results.ToArray() + }; + } + + public async Task CalculateMutipleAsync(ComplexCalculationContext context) + { + var results = new List(); + results.AddRange(context.Calculations.Select(c => new CalculationResult { Result = c.A + c.B })); + + await Task.Delay(2500); + + return new ComplexCalculationResult + { + Results = results.ToArray() + }; + } + } +} diff --git a/Vendor/Prise.Tests.Integration/IntegrationTestsPlugins/PluginA/PluginA.csproj b/Vendor/Prise.Tests.Integration/IntegrationTestsPlugins/PluginA/PluginA.csproj new file mode 100644 index 0000000..e283a0e --- /dev/null +++ b/Vendor/Prise.Tests.Integration/IntegrationTestsPlugins/PluginA/PluginA.csproj @@ -0,0 +1,12 @@ + + + + netstandard2.1 + + + + + + + + diff --git a/Vendor/Prise.Tests.Integration/IntegrationTestsPlugins/PluginA/PluginA.net2.csproj b/Vendor/Prise.Tests.Integration/IntegrationTestsPlugins/PluginA/PluginA.net2.csproj new file mode 100644 index 0000000..2924c3b --- /dev/null +++ b/Vendor/Prise.Tests.Integration/IntegrationTestsPlugins/PluginA/PluginA.net2.csproj @@ -0,0 +1,13 @@ + + + + netstandard2.0 + PluginA + + + + + + + + diff --git a/Vendor/Prise.Tests.Integration/IntegrationTestsPlugins/PluginA/ZAdditionPlusOneCalculationPlugin.cs b/Vendor/Prise.Tests.Integration/IntegrationTestsPlugins/PluginA/ZAdditionPlusOneCalculationPlugin.cs new file mode 100644 index 0000000..863bc62 --- /dev/null +++ b/Vendor/Prise.Tests.Integration/IntegrationTestsPlugins/PluginA/ZAdditionPlusOneCalculationPlugin.cs @@ -0,0 +1,65 @@ +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Prise.IntegrationTestsContract; +using Prise.Plugin; + +namespace PluginA +{ + /// + /// By default, only the first plugin is loaded, the first in alphabethical order + /// In order to execute the ZAdditionPlusOneCalculationPlugin, you need to have an IEnumerable injected + /// or inject a IPluginLoader and call the .LoadAll() method. + /// + [Plugin(PluginType = typeof(ICalculationPlugin))] + public class ZAdditionPlusOneCalculationPlugin : ICalculationPlugin + { + public string Name => nameof(ZAdditionPlusOneCalculationPlugin); + public string Description => "This plugin performs addition +1"; + public int Calculate(int a, int b) + { + return a + b + 1; + } + + public decimal Calculate(decimal a, decimal b) + { + return a + b + 1; + } + + public decimal CalculateComplex(CalculationContext context) + { + return context.A + context.B + 1; + } + + public CalculationResult CalculateComplexResult(CalculationContext context) + { + return new CalculationResult + { + Result = context.A + context.B + 1 + }; + } + + public ComplexCalculationResult CalculateMutiple(ComplexCalculationContext context) + { + var results = new List(); + results.AddRange(context.Calculations.Select(c => new CalculationResult { Result = c.A + c.B + 1 })); + return new ComplexCalculationResult + { + Results = results.ToArray() + }; + } + + public async Task CalculateMutipleAsync(ComplexCalculationContext context) + { + var results = new List(); + results.AddRange(context.Calculations.Select(c => new CalculationResult { Result = c.A + c.B + 1 })); + + await Task.Delay(2500); + + return new ComplexCalculationResult + { + Results = results.ToArray() + }; + } + } +} \ No newline at end of file diff --git a/Vendor/Prise.Tests.Integration/IntegrationTestsPlugins/PluginA/prise.plugin.json b/Vendor/Prise.Tests.Integration/IntegrationTestsPlugins/PluginA/prise.plugin.json new file mode 100644 index 0000000..c41a328 --- /dev/null +++ b/Vendor/Prise.Tests.Integration/IntegrationTestsPlugins/PluginA/prise.plugin.json @@ -0,0 +1,6 @@ +{ + "publishDir": "../../_dist", + "configuration": "Debug", + "nuspecFile": null, + "includeProjectNameInPublishDir": true +} \ No newline at end of file diff --git a/Vendor/Prise.Tests.Integration/IntegrationTestsPlugins/PluginB/PluginB.csproj b/Vendor/Prise.Tests.Integration/IntegrationTestsPlugins/PluginB/PluginB.csproj new file mode 100644 index 0000000..523da87 --- /dev/null +++ b/Vendor/Prise.Tests.Integration/IntegrationTestsPlugins/PluginB/PluginB.csproj @@ -0,0 +1,11 @@ + + + + netstandard2.1 + + + + + + + diff --git a/Vendor/Prise.Tests.Integration/IntegrationTestsPlugins/PluginB/PluginB.net2.csproj b/Vendor/Prise.Tests.Integration/IntegrationTestsPlugins/PluginB/PluginB.net2.csproj new file mode 100644 index 0000000..cdc0528 --- /dev/null +++ b/Vendor/Prise.Tests.Integration/IntegrationTestsPlugins/PluginB/PluginB.net2.csproj @@ -0,0 +1,12 @@ + + + + netstandard2.0 + PluginB + + + + + + + diff --git a/Vendor/Prise.Tests.Integration/IntegrationTestsPlugins/PluginB/SubtractionCalculationPlugin.cs b/Vendor/Prise.Tests.Integration/IntegrationTestsPlugins/PluginB/SubtractionCalculationPlugin.cs new file mode 100644 index 0000000..681b9a8 --- /dev/null +++ b/Vendor/Prise.Tests.Integration/IntegrationTestsPlugins/PluginB/SubtractionCalculationPlugin.cs @@ -0,0 +1,65 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Prise.IntegrationTestsContract; +using Prise.Plugin; + +namespace PluginB +{ + // This class does not implement the ICalculationPlugin interface + // Since all the methods are present, it will continue to work because the PluginAttribute is still present and the interface contract is respected + // This improves backwards compatibility. + [Plugin(PluginType = typeof(ICalculationPlugin))] + public class SubtractionCalculationPlugin + { + public string Name => nameof(SubtractionCalculationPlugin); + + // Property Description will not be implemented in this plugin, all other methods can still be called + // public string Description => "This plugin performs subtraction"; + // However, you could expose it this way: + // public string get_Description() => "This plugin performs subtraction"; + public int Calculate(int a, int b) + { + return a - b; + } + + public decimal Calculate(decimal a, decimal b) + { + return a - b; + } + + public decimal CalculateComplex(CalculationContext context) + { + return context.A - context.B; + } + + public CalculationResult CalculateComplexResult(CalculationContext context) + { + return new CalculationResult { Result = context.A - context.B }; + } + + public ComplexCalculationResult CalculateMutiple(ComplexCalculationContext context) + { + var results = new List(); + results.AddRange(context.Calculations.Select(c => new CalculationResult { Result = c.A - c.B })); + return new ComplexCalculationResult + { + Results = results.ToArray() + }; + } + + public async Task CalculateMutipleAsync(ComplexCalculationContext context) + { + var results = new List(); + results.AddRange(context.Calculations.Select(c => new CalculationResult { Result = c.A - c.B })); + + await Task.Delay(2500); + + return new ComplexCalculationResult + { + Results = results.ToArray() + }; + } + } +} diff --git a/Vendor/Prise.Tests.Integration/IntegrationTestsPlugins/PluginB/prise.plugin.json b/Vendor/Prise.Tests.Integration/IntegrationTestsPlugins/PluginB/prise.plugin.json new file mode 100644 index 0000000..c41a328 --- /dev/null +++ b/Vendor/Prise.Tests.Integration/IntegrationTestsPlugins/PluginB/prise.plugin.json @@ -0,0 +1,6 @@ +{ + "publishDir": "../../_dist", + "configuration": "Debug", + "nuspecFile": null, + "includeProjectNameInPublishDir": true +} \ No newline at end of file diff --git a/Vendor/Prise.Tests.Integration/IntegrationTestsPlugins/PluginC/Calculations/ICanCalculate.cs b/Vendor/Prise.Tests.Integration/IntegrationTestsPlugins/PluginC/Calculations/ICanCalculate.cs new file mode 100644 index 0000000..0707aa4 --- /dev/null +++ b/Vendor/Prise.Tests.Integration/IntegrationTestsPlugins/PluginC/Calculations/ICanCalculate.cs @@ -0,0 +1,31 @@ +using DomainForPluginC; + +namespace PluginC.Calculations +{ + public interface ICanCalculate + { + decimal DoCalculation(decimal a, decimal b); + } + + public class DivideCalculation : ICanCalculate + { + public decimal DoCalculation(decimal a, decimal b) + { + return a / b; + } + } + + public class MultiplyCalculation : ICanCalculate + { + private readonly IDiscountService discountService; + public MultiplyCalculation(IDiscountService discountService) + { + this.discountService = discountService; + } + + public decimal DoCalculation(decimal a, decimal b) + { + return this.discountService.ApplyDiscount((a * b)); + } + } +} \ No newline at end of file diff --git a/Vendor/Prise.Tests.Integration/IntegrationTestsPlugins/PluginC/DivideOrMultiplyCalculationBootstrapper.cs b/Vendor/Prise.Tests.Integration/IntegrationTestsPlugins/PluginC/DivideOrMultiplyCalculationBootstrapper.cs new file mode 100644 index 0000000..098a0eb --- /dev/null +++ b/Vendor/Prise.Tests.Integration/IntegrationTestsPlugins/PluginC/DivideOrMultiplyCalculationBootstrapper.cs @@ -0,0 +1,31 @@ +using System; +using DomainForPluginC; +using Microsoft.Extensions.DependencyInjection; +using PluginC.Calculations; +using Prise.Plugin; + +namespace PluginC +{ + [PluginBootstrapper(PluginType = typeof(DivideOrMultiplyCalculationPlugin))] + public class DivideOrMultiplyCalculationBootstrapper : IPluginBootstrapper + { + public IServiceCollection Bootstrap(IServiceCollection services) + { + // Discount and DiscountService come from a third party assembly called Domain + // Add a fixed discount of 10% + services.AddSingleton(new Discount(1.10m)); + services.AddScoped(); + + // Randomly choose what service to use + // var random = new Random(); + // if (random.Next() % 2 == 0) + // services.AddScoped(); + // else + // services.AddScoped(); + + services.AddScoped(); + + return services; + } + } +} \ No newline at end of file diff --git a/Vendor/Prise.Tests.Integration/IntegrationTestsPlugins/PluginC/DivideOrMultiplyCalculationPlugin.cs b/Vendor/Prise.Tests.Integration/IntegrationTestsPlugins/PluginC/DivideOrMultiplyCalculationPlugin.cs new file mode 100644 index 0000000..197ee42 --- /dev/null +++ b/Vendor/Prise.Tests.Integration/IntegrationTestsPlugins/PluginC/DivideOrMultiplyCalculationPlugin.cs @@ -0,0 +1,75 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Prise.IntegrationTestsContract; +using PluginC.Calculations; +using Prise.Plugin; +using System.Threading.Tasks; + +namespace PluginC +{ + // This plugin will Divide or Multiple, who knows, it's always a guess. + // The decision is made in a service, which dependend a discount from a third party dependency that no other plugin shares + [Plugin(PluginType = typeof(ICalculationPlugin))] + public class DivideOrMultiplyCalculationPlugin : ICalculationPlugin + { + public string Name => nameof(DivideOrMultiplyCalculationPlugin); + + public string Description => $"This plugin performs division OR multiplication, check out {nameof(DivideOrMultiplyCalculationBootstrapper)} for more details"; + private readonly ICanCalculate calculation; + + internal DivideOrMultiplyCalculationPlugin(ICanCalculate calculation) + { + this.calculation = calculation; + } + + public int Calculate(int a, int b) + { + return (int)this.calculation.DoCalculation(a, b); + } + + public decimal Calculate(decimal a, decimal b) + { + return this.calculation.DoCalculation(a, b); + } + + public decimal CalculateComplex(CalculationContext context) + { + return this.calculation.DoCalculation(context.A, context.B); + } + + public CalculationResult CalculateComplexResult(CalculationContext context) + { + return new CalculationResult { Result = this.calculation.DoCalculation(context.A, context.B) }; + } + + public ComplexCalculationResult CalculateMutiple(ComplexCalculationContext context) + { + var results = new List(); + results.AddRange(context.Calculations.Select(c => new CalculationResult { Result = this.calculation.DoCalculation(c.A, c.B) })); + return new ComplexCalculationResult + { + Results = results.ToArray() + }; + } + + public async Task CalculateMutipleAsync(ComplexCalculationContext context) + { + var results = new List(); + results.AddRange(context.Calculations.Select(c => new CalculationResult { Result = this.calculation.DoCalculation(c.A, c.B) })); + + await Task.Delay(2500); + + return new ComplexCalculationResult + { + Results = results.ToArray() + }; + } + + [PluginFactory] + public static ICalculationPlugin ThisNameDoesNotMatterFactoryMethod(IServiceProvider serviceProvider) + { + return new DivideOrMultiplyCalculationPlugin((ICanCalculate)serviceProvider.GetService(typeof(ICanCalculate))); + } + } +} diff --git a/Vendor/Prise.Tests.Integration/IntegrationTestsPlugins/PluginC/PluginC.csproj b/Vendor/Prise.Tests.Integration/IntegrationTestsPlugins/PluginC/PluginC.csproj new file mode 100644 index 0000000..8a6fd74 --- /dev/null +++ b/Vendor/Prise.Tests.Integration/IntegrationTestsPlugins/PluginC/PluginC.csproj @@ -0,0 +1,12 @@ + + + + netcoreapp3.1 + + + + + + + + diff --git a/Vendor/Prise.Tests.Integration/IntegrationTestsPlugins/PluginC/PluginC.net2.csproj b/Vendor/Prise.Tests.Integration/IntegrationTestsPlugins/PluginC/PluginC.net2.csproj new file mode 100644 index 0000000..74550a0 --- /dev/null +++ b/Vendor/Prise.Tests.Integration/IntegrationTestsPlugins/PluginC/PluginC.net2.csproj @@ -0,0 +1,13 @@ + + + + netstandard2.0 + PluginC + + + + + + + + diff --git a/Vendor/Prise.Tests.Integration/IntegrationTestsPlugins/PluginC/prise.plugin.json b/Vendor/Prise.Tests.Integration/IntegrationTestsPlugins/PluginC/prise.plugin.json new file mode 100644 index 0000000..c41a328 --- /dev/null +++ b/Vendor/Prise.Tests.Integration/IntegrationTestsPlugins/PluginC/prise.plugin.json @@ -0,0 +1,6 @@ +{ + "publishDir": "../../_dist", + "configuration": "Debug", + "nuspecFile": null, + "includeProjectNameInPublishDir": true +} \ No newline at end of file diff --git a/Vendor/Prise.Tests.Integration/Prise.IntegrationTests/AppHostCollection.cs b/Vendor/Prise.Tests.Integration/Prise.IntegrationTests/AppHostCollection.cs new file mode 100644 index 0000000..7375dfb --- /dev/null +++ b/Vendor/Prise.Tests.Integration/Prise.IntegrationTests/AppHostCollection.cs @@ -0,0 +1,12 @@ +using Xunit; + +namespace Prise.IntegrationTests +{ + [CollectionDefinition("AppHost collection")] + public class AppHostCollection : ICollectionFixture + { + // This class has no code, and is never created. Its purpose is simply + // to be the place to apply [CollectionDefinition] and all the + // ICollectionFixture<> interfaces. + } +} diff --git a/Vendor/Prise.Tests.Integration/Prise.IntegrationTests/AppHostWebApplicationFactory.cs b/Vendor/Prise.Tests.Integration/Prise.IntegrationTests/AppHostWebApplicationFactory.cs new file mode 100644 index 0000000..de366e5 --- /dev/null +++ b/Vendor/Prise.Tests.Integration/Prise.IntegrationTests/AppHostWebApplicationFactory.cs @@ -0,0 +1,27 @@ +using System.Collections.Generic; +using Microsoft.AspNetCore.Mvc.Testing; +using Prise.IntegrationTestsHost; + +namespace Prise.IntegrationTests +{ + public class CommandLineArgumentsLazy : ICommandLineArguments + { + public bool UseLazyService { get; set; } + public bool UseCollectibleAssemblies { get; set; } + } + + public partial class AppHostWebApplicationFactory + : WebApplicationFactory + { + internal static AppHostWebApplicationFactory _instance = new AppHostWebApplicationFactory(new CommandLineArgumentsLazy(), null); + internal static AppHostWebApplicationFactory Default() => _instance; + + private readonly Dictionary settings; + private readonly ICommandLineArguments commandLineArguments; + public AppHostWebApplicationFactory(ICommandLineArguments commandLineArguments, Dictionary settings = null) + { + this.commandLineArguments = commandLineArguments; + this.settings = settings; + } + } +} \ No newline at end of file diff --git a/Vendor/Prise.Tests.Integration/Prise.IntegrationTests/AppHostWebApplicationFactory.netcore2.cs b/Vendor/Prise.Tests.Integration/Prise.IntegrationTests/AppHostWebApplicationFactory.netcore2.cs new file mode 100644 index 0000000..f3c4d1e --- /dev/null +++ b/Vendor/Prise.Tests.Integration/Prise.IntegrationTests/AppHostWebApplicationFactory.netcore2.cs @@ -0,0 +1,24 @@ +using Prise.IntegrationTestsHost; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Mvc.Testing; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Configuration; + +namespace Prise.IntegrationTests +{ + public partial class AppHostWebApplicationFactory + : WebApplicationFactory + { +#if NETCORE2_1 + protected override void ConfigureWebHost(IWebHostBuilder builder) + { + builder.ConfigureAppConfiguration((c, b) => b.AddInMemoryCollection(this.settings)); + builder.ConfigureServices(services => + { + services.AddSingleton((s) => this.commandLineArguments); + }); + } +#endif + } +} \ No newline at end of file diff --git a/Vendor/Prise.Tests.Integration/Prise.IntegrationTests/AppHostWebApplicationFactory.netcore3.cs b/Vendor/Prise.Tests.Integration/Prise.IntegrationTests/AppHostWebApplicationFactory.netcore3.cs new file mode 100644 index 0000000..8b6967f --- /dev/null +++ b/Vendor/Prise.Tests.Integration/Prise.IntegrationTests/AppHostWebApplicationFactory.netcore3.cs @@ -0,0 +1,27 @@ +using Prise.IntegrationTestsHost; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Mvc.Testing; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Configuration; + +namespace Prise.IntegrationTests +{ + public partial class AppHostWebApplicationFactory + : WebApplicationFactory + { +#if NETCORE3_1 + protected override IHostBuilder CreateHostBuilder() + { + return Host.CreateDefaultBuilder() + .ConfigureServices((hostContext, services) => + services.AddSingleton((s) => this.commandLineArguments)) + .ConfigureWebHostDefaults(webBuilder => + { + webBuilder.UseStartup(); + webBuilder.ConfigureAppConfiguration(builder => builder.AddInMemoryCollection(this.settings)); + }); + } +#endif + } +} \ No newline at end of file diff --git a/Vendor/Prise.Tests.Integration/Prise.IntegrationTests/BreakTheServerTests.cs b/Vendor/Prise.Tests.Integration/Prise.IntegrationTests/BreakTheServerTests.cs new file mode 100644 index 0000000..2c4aba8 --- /dev/null +++ b/Vendor/Prise.Tests.Integration/Prise.IntegrationTests/BreakTheServerTests.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading.Tasks; +using Xunit; + +namespace Prise.IntegrationTests +{ +#if NETCORE3_1 + public class BreakTheServerTests : CalculationPluginTestsBase + { + public BreakTheServerTests() : base(AppHostWebApplicationFactory.Default()) { } + + [Fact] + public async Task BreakWithLoop() + { + var tasks = new List>(); + for (var i = 0; i < 250; i++) + { + tasks.Add(GetRaw(_client, "PluginA", "/disco")); + } + + var results = await Task.WhenAll(tasks.ToArray()); + + Assert.All(results, s => Assert.Equal("AdditionCalculationPlugin,ZAdditionPlusOneCalculationPlugin", s)); + + } + } +#endif +} diff --git a/Vendor/Prise.Tests.Integration/Prise.IntegrationTests/CalculationPluginTestsBase.cs b/Vendor/Prise.Tests.Integration/Prise.IntegrationTests/CalculationPluginTestsBase.cs new file mode 100644 index 0000000..b745b92 --- /dev/null +++ b/Vendor/Prise.Tests.Integration/Prise.IntegrationTests/CalculationPluginTestsBase.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.Net.Http; +using System.Text; +using System.Threading.Tasks; +using Newtonsoft.Json; + +namespace Prise.IntegrationTests +{ + public abstract class CalculationPluginTestsBase : PluginTestBase + { + protected CalculationPluginTestsBase(AppHostWebApplicationFactory factory) : base(factory) { } + + protected async Task Post(HttpClient client, string pluginType, string endpoint, object content) + { + client.DefaultRequestHeaders.Add("PluginType", pluginType); + var response = await client.PostAsync(endpoint, new StringContent(JsonConvert.SerializeObject(content), Encoding.UTF8, + "application/json")); + if (!response.IsSuccessStatusCode) + throw new Exception("Result was not success!"); + + var responseContent = await response.Content.ReadAsStringAsync(); + return JsonConvert.DeserializeObject(responseContent); + } + + protected async Task GetRaw(HttpClient client, string pluginType, string endpoint) + { + client.DefaultRequestHeaders.Add("PluginType", pluginType); + var response = await client.GetAsync(endpoint); + if (!response.IsSuccessStatusCode) + throw new Exception("Result was not success!"); + + return await response.Content.ReadAsStringAsync(); + } + } +} diff --git a/Vendor/Prise.Tests.Integration/Prise.IntegrationTests/CalculationTests.cs b/Vendor/Prise.Tests.Integration/Prise.IntegrationTests/CalculationTests.cs new file mode 100644 index 0000000..e34d62b --- /dev/null +++ b/Vendor/Prise.Tests.Integration/Prise.IntegrationTests/CalculationTests.cs @@ -0,0 +1,329 @@ +using System.Net.Http; +using System.Threading.Tasks; +using Prise.IntegrationTestsHost.Models; +using Microsoft.AspNetCore.Mvc.Testing; +using Xunit; + +namespace Prise.IntegrationTests +{ + public class CalculationTests : CalculationPluginTestsBase + { + public CalculationTests() : base(AppHostWebApplicationFactory.Default()) { } + + [Fact] + public async Task PluginA_Works() + { + // Arrange + var payload = new CalculationRequestModel + { + A = 100, + B = 150 + }; + + //Act + var result = await Post(_client, "PluginA", "/calculation", payload); + + // Assert 100 + 150 + Assert.Equal(250, result.Result); + } + + [Fact] + public async Task PluginB_Works() + { + // Arrange + var payload = new CalculationRequestModel + { + A = 150, + B = 50 + }; + + //Act + var result = await Post(_client, "PluginB", "/calculation", payload); + + // Assert 150 - 50 + Assert.Equal(100, result.Result); + } + + [Fact] + public async Task PluginC_Works() + { + // Arrange + var payload = new CalculationRequestModel + { + A = 50, + B = 2 + }; + + //Act + var result = await Post(_client, "PluginC", "/calculation", payload); + + // Assert 50 * 2 + 10% discount + Assert.Equal(110, result.Result); + } + + [Fact] + public async Task PluginA_int_Works() + { + // Arrange + var payload = new CalculationRequestModel + { + A = 100, + B = 150 + }; + + //Act + var result = await Post(_client, "PluginA", "/calculation/int", payload); + + // Assert 100 + 150 + Assert.Equal(250, result.Result); + } + + [Fact] + public async Task PluginB_int_Works() + { + // Arrange + var payload = new CalculationRequestModel + { + A = 150, + B = 50 + }; + + //Act + var result = await Post(_client, "PluginB", "/calculation/int", payload); + + // Assert 150 - 50 + Assert.Equal(100, result.Result); + } + + [Fact] + public async Task PluginC_int_Works() + { + // Arrange + var payload = new CalculationRequestModel + { + A = 50, + B = 2 + }; + + //Act + var result = await Post(_client, "PluginC", "/calculation/int", payload); + + // Assert 50 * 2 + 10% discount + Assert.Equal(110, result.Result); + } + + [Fact] + public async Task PluginA_complex_input_Works() + { + // Arrange + var payload = new CalculationRequestModel + { + A = 100, + B = 150 + }; + + //Act + var result = await Post(_client, "PluginA", "/calculation/complex-input", payload); + + // Assert 100 + 150 + Assert.Equal(250, result.Result); + } + + [Fact] + public async Task PluginB_complex_input_Works() + { + // Arrange + var payload = new CalculationRequestModel + { + A = 150, + B = 50 + }; + + //Act + var result = await Post(_client, "PluginB", "/calculation/complex-input", payload); + + // Assert 150 - 50 + Assert.Equal(100, result.Result); + } + + [Fact] + public async Task PluginC_complex_input_Works() + { + // Arrange + var payload = new CalculationRequestModel + { + A = 50, + B = 2 + }; + + //Act + var result = await Post(_client, "PluginC", "/calculation/complex-input", payload); + + // Assert 50 * 2 + 10% discount + Assert.Equal(110, result.Result); + } + + [Fact] + public async Task PluginA_complex_output_Works() + { + // Arrange + var payload = new CalculationRequestModel + { + A = 100, + B = 150 + }; + + //Act + var result = await Post(_client, "PluginA", "/calculation/complex-output", payload); + + // Assert 100 + 150 + Assert.Equal(250, result.Result); + } + + [Fact] + public async Task PluginB_complex_output_Works() + { + // Arrange + var payload = new CalculationRequestModel + { + A = 150, + B = 50 + }; + + //Act + var result = await Post(_client, "PluginB", "/calculation/complex-output", payload); + + // Assert 150 - 50 + Assert.Equal(100, result.Result); + } + + [Fact] + public async Task PluginC_complex_output_Works() + { + // Arrange + var payload = new CalculationRequestModel + { + A = 50, + B = 2 + }; + + //Act + var result = await Post(_client, "PluginC", "/calculation/complex-output", payload); + + // Assert 50 * 2 + 10% discount + Assert.Equal(110, result.Result); + } + + [Fact] + public async Task PluginA_multi_Works() + { + // Arrange + var payload = new CalculationRequestMultiModel + { + Calculations = new[] + { + new CalculationRequestModel + { + A = 100, + B = 150 + }, + new CalculationRequestModel + { + A = 100, + B = 150 + } + } + }; + + //Act + var result = await Post(_client, "PluginA", "/calculation/multi", payload); + + // Assert 100 + 150 + 100 + 150 + Assert.Equal(500, result.Result); + } + + [Fact] + public async Task PluginB_multi_Works() + { + // Arrange + var payload = new CalculationRequestMultiModel + { + Calculations = new[] + { + new CalculationRequestModel + { + A = 50, + B = 5 + }, + new CalculationRequestModel + { + A = 40, + B = 5 + } + } + }; + + //Act + var result = await Post(_client, "PluginB", "/calculation/multi", payload); + + // Assert (50 - 5) + (40 - 5) + Assert.Equal(80, result.Result); + } + + [Fact] + public async Task PluginC_multi_Works() + { + // Arrange + var payload = new CalculationRequestMultiModel + { + Calculations = new[] + { + new CalculationRequestModel + { + A = 50, + B = 2 + }, + new CalculationRequestModel + { + A = 40, + B = 2 + } + } + }; + + //Act + var result = await Post(_client, "PluginC", "/calculation/multi", payload); + + // Assert (50 * 2 + 10% discount) + (40 * 2 + 10% discount) + Assert.Equal(198, result.Result); + } + + [Fact] + public async Task PluginC_multi_async_Works() + { + // Arrange + var payload = new CalculationRequestMultiModel + { + Calculations = new[] + { + new CalculationRequestModel + { + A = 50, + B = 2 + }, + new CalculationRequestModel + { + A = 40, + B = 2 + } + } + }; + + //Act + var result = await Post(_client, "PluginC", "/calculation/multi-async", payload); + + // Assert (50 * 2 + 10% discount) + (40 * 2 + 10% discount) + Assert.Equal(198, result.Result); + } + } +} diff --git a/Vendor/Prise.Tests.Integration/Prise.IntegrationTests/DiscoTests.cs b/Vendor/Prise.Tests.Integration/Prise.IntegrationTests/DiscoTests.cs new file mode 100644 index 0000000..5df2776 --- /dev/null +++ b/Vendor/Prise.Tests.Integration/Prise.IntegrationTests/DiscoTests.cs @@ -0,0 +1,61 @@ +using System.Threading.Tasks; +using Xunit; + +namespace Prise.IntegrationTests +{ + public class DiscoTests : CalculationPluginTestsBase + { + public DiscoTests() : base(AppHostWebApplicationFactory.Default()) { } + + [Fact] + public async Task PluginA_Works() + { + // Arrange, Act + var result = await GetRaw(_client, "PluginA", "/disco"); + + // Assert + Assert.Equal("AdditionCalculationPlugin,ZAdditionPlusOneCalculationPlugin", result); + } + + [Fact] + public async Task PluginA_Description_Works() + { + // Arrange, Act + + var result = await GetRaw(_client, "PluginA", "/disco/description"); + + // Assert + Assert.Equal("This plugin performs addition,This plugin performs addition +1", result); + } + + [Fact] + public async Task PluginB_Works() + { + // Arrange, Act + var result = await GetRaw(_client, "PluginB", "/disco"); + + // Assert + Assert.Equal("SubtractionCalculationPlugin", result); + } + + [Fact] + public async Task PluginC_Works() + { + // Arrange, Act + var result = await GetRaw(_client, "PluginC", "/disco"); + + // Assert + Assert.Equal("DivideOrMultiplyCalculationPlugin", result); + } + + [Fact] + public async Task PluginC_Description_Works() + { + // Arrange, Act + var result = await GetRaw(_client, "PluginC", "/disco/description"); + + // Assert + Assert.Equal("This plugin performs division OR multiplication, check out DivideOrMultiplyCalculationBootstrapper for more details", result); + } + } +} diff --git a/Vendor/Prise.Tests.Integration/Prise.IntegrationTests/MultipleTests.cs b/Vendor/Prise.Tests.Integration/Prise.IntegrationTests/MultipleTests.cs new file mode 100644 index 0000000..790111c --- /dev/null +++ b/Vendor/Prise.Tests.Integration/Prise.IntegrationTests/MultipleTests.cs @@ -0,0 +1,64 @@ +using System.Net.Http; +using System.Threading.Tasks; +using Prise.IntegrationTestsHost.Models; +using Microsoft.AspNetCore.Mvc.Testing; +using Xunit; + +namespace Prise.IntegrationTests +{ + public class MultipleTests : CalculationPluginTestsBase + { + public MultipleTests() : base(AppHostWebApplicationFactory.Default()) { } + + [Fact] + public async Task PluginA_Works() + { + // Arrange + var payload = new CalculationRequestModel + { + A = 100, + B = 150 + }; + + //Act + var result = await Post(_client, "PluginA", "/multiple", payload); + + // Assert (100 + 150) + (100 + 150 + 1) + Assert.Equal(501, result.Result); + } + + [Fact] + public async Task PluginB_Works() + { + // Arrange + var payload = new CalculationRequestModel + { + A = 150, + B = 50 + }; + + //Act + var result = await Post(_client, "PluginB", "/multiple", payload); + + // Assert 150 - 50 + Assert.Equal(100, result.Result); + } + + [Fact] + public async Task PluginC_Works() + { + // Arrange + var payload = new CalculationRequestModel + { + A = 50, + B = 2 + }; + + //Act + var result = await Post(_client, "PluginC", "/multiple", payload); + + // Assert 50 * 2 + 10% discount + Assert.Equal(110, result.Result); + } + } +} diff --git a/Vendor/Prise.Tests.Integration/Prise.IntegrationTests/PluginTestBase.cs b/Vendor/Prise.Tests.Integration/Prise.IntegrationTests/PluginTestBase.cs new file mode 100644 index 0000000..a7720d5 --- /dev/null +++ b/Vendor/Prise.Tests.Integration/Prise.IntegrationTests/PluginTestBase.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Net.Http; +using System.Text; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc.Testing; +using Newtonsoft.Json; +using Prise.IntegrationTestsContract; + +namespace Prise.IntegrationTests +{ + public abstract class PluginTestBase + { + protected readonly HttpClient _client; + protected readonly AppHostWebApplicationFactory _factory; + + protected PluginTestBase( + AppHostWebApplicationFactory factory) + { + _factory = factory; + var local = Environment.GetEnvironmentVariable("LOCAL") == "true"; + if (local) + { + _client = new HttpClient(); + _client.BaseAddress = new Uri("https://localhost:5001"); + } + else + _client = factory.CreateClient(new WebApplicationFactoryClientOptions + { + AllowAutoRedirect = false, + BaseAddress = new Uri("https://localhost:5001") + }); + _client.Timeout = new TimeSpan(0, 5, 0); + } + } +} \ No newline at end of file diff --git a/Vendor/Prise.Tests.Integration/Prise.IntegrationTests/Prise.IntegrationTests.csproj b/Vendor/Prise.Tests.Integration/Prise.IntegrationTests/Prise.IntegrationTests.csproj new file mode 100644 index 0000000..6df4969 --- /dev/null +++ b/Vendor/Prise.Tests.Integration/Prise.IntegrationTests/Prise.IntegrationTests.csproj @@ -0,0 +1,25 @@ + + + + net6.0 + false + + + + NETCORE3_1 + + + + + + + + + + + + + + + + diff --git a/Vendor/Prise.Tests.Integration/Prise.IntegrationTests/Properties/launchSettings.json b/Vendor/Prise.Tests.Integration/Prise.IntegrationTests/Properties/launchSettings.json new file mode 100644 index 0000000..074d907 --- /dev/null +++ b/Vendor/Prise.Tests.Integration/Prise.IntegrationTests/Properties/launchSettings.json @@ -0,0 +1,10 @@ +{ + "profiles": { + "Prise.IntegrationTests": { + "commandName": "Project", + "environmentVariables": { + "LOCAL": "true" + } + } + } +} \ No newline at end of file diff --git a/Vendor/Prise.Tests.Integration/Prise.IntegrationTests/SadPathTests.cs b/Vendor/Prise.Tests.Integration/Prise.IntegrationTests/SadPathTests.cs new file mode 100644 index 0000000..35a4816 --- /dev/null +++ b/Vendor/Prise.Tests.Integration/Prise.IntegrationTests/SadPathTests.cs @@ -0,0 +1,45 @@ +using System; +using System.Net.Http; +using System.Threading.Tasks; +using Prise.IntegrationTestsHost.Models; +using Microsoft.AspNetCore.Mvc.Testing; +using Xunit; + +namespace Prise.IntegrationTests +{ + public class SadPathTests : CalculationPluginTestsBase + { + public SadPathTests() : base(AppHostWebApplicationFactory.Default()) { } + + [Fact] + public async Task PluginZ_DoesNotExists() + { + // Arrange + var payload = new CalculationRequestModel + { + A = 100, + B = 150 + }; + + //Act +#if NETCORE3_1 + await Assert.ThrowsAsync(async () => await Post(_client, "PluginZ", "/calculation", payload)); +#endif +#if NETCORE2_1 + await Assert.ThrowsAsync(async () => await Post(_client, "PluginZ", "/calculation", payload)); +#endif + } + + [Fact] + public async Task PluginB_Description_Does_Not_Work() + { + // Arrange, Act +#if NETCORE3_1 + await Assert.ThrowsAsync(async () => await GetRaw(_client, "PluginB", "/disco/description")); +#endif +#if NETCORE2_1 + await Assert.ThrowsAsync(async () => await GetRaw(_client, "PluginB", "/disco/description")); +#endif + } + } +} diff --git a/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsContract/CalculationContext.cs b/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsContract/CalculationContext.cs new file mode 100644 index 0000000..ec2a0b5 --- /dev/null +++ b/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsContract/CalculationContext.cs @@ -0,0 +1,11 @@ +using System; + +namespace Prise.IntegrationTestsContract +{ + // Plugin Parameter types are not required to be serializable, Newtonsoft JSON takes care of this + public class CalculationContext + { + public decimal A { get; set; } + public decimal B { get; set; } + } +} \ No newline at end of file diff --git a/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsContract/CalculationResult.cs b/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsContract/CalculationResult.cs new file mode 100644 index 0000000..0756fcb --- /dev/null +++ b/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsContract/CalculationResult.cs @@ -0,0 +1,9 @@ +using System; + +namespace Prise.IntegrationTestsContract +{ + public class CalculationResult + { + public decimal Result { get; set; } + } +} \ No newline at end of file diff --git a/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsContract/ComplexCalculationContext.cs b/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsContract/ComplexCalculationContext.cs new file mode 100644 index 0000000..49c13b1 --- /dev/null +++ b/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsContract/ComplexCalculationContext.cs @@ -0,0 +1,10 @@ +using System; + +namespace Prise.IntegrationTestsContract +{ + // Plugin Parameter types are not required to be serializable, Newtonsoft JSON takes care of this + public class ComplexCalculationContext + { + public CalculationContext[] Calculations { get; set; } + } +} \ No newline at end of file diff --git a/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsContract/ComplexCalculationResult.cs b/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsContract/ComplexCalculationResult.cs new file mode 100644 index 0000000..cb0f3a8 --- /dev/null +++ b/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsContract/ComplexCalculationResult.cs @@ -0,0 +1,9 @@ +using System; + +namespace Prise.IntegrationTestsContract +{ + public class ComplexCalculationResult + { + public CalculationResult[] Results { get; set; } + } +} \ No newline at end of file diff --git a/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsContract/IAuthenticatedDataService.cs b/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsContract/IAuthenticatedDataService.cs new file mode 100644 index 0000000..55b0d3b --- /dev/null +++ b/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsContract/IAuthenticatedDataService.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading.Tasks; + +namespace Prise.IntegrationTestsContract +{ + public class Data + { + public int Id { get; set; } + public string Name { get; set; } + public decimal Amount { get; set; } + public IEnumerable Children { get; set; } + } + + public interface IAuthenticatedDataService + { + Task> GetData(string token); + } +} diff --git a/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsContract/ICalculationPlugin.cs b/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsContract/ICalculationPlugin.cs new file mode 100644 index 0000000..cb5f0a9 --- /dev/null +++ b/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsContract/ICalculationPlugin.cs @@ -0,0 +1,17 @@ +using System; +using System.Threading.Tasks; + +namespace Prise.IntegrationTestsContract +{ + public interface ICalculationPlugin + { + string Name { get; } + string Description { get; } + int Calculate(int a, int b); + decimal Calculate(decimal a, decimal b); + decimal CalculateComplex(CalculationContext context); + CalculationResult CalculateComplexResult(CalculationContext context); + ComplexCalculationResult CalculateMutiple(ComplexCalculationContext context); + Task CalculateMutipleAsync(ComplexCalculationContext context); + } +} diff --git a/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsContract/INetworkCalculationPlugin.cs b/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsContract/INetworkCalculationPlugin.cs new file mode 100644 index 0000000..17c7d4d --- /dev/null +++ b/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsContract/INetworkCalculationPlugin.cs @@ -0,0 +1,6 @@ +namespace Prise.IntegrationTestsContract +{ + public interface INetworkCalculationPlugin : ICalculationPlugin + { + } +} diff --git a/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsContract/IPluginWithSerializer.cs b/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsContract/IPluginWithSerializer.cs new file mode 100644 index 0000000..7b81f0e --- /dev/null +++ b/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsContract/IPluginWithSerializer.cs @@ -0,0 +1,14 @@ +namespace Prise.IntegrationTestsContract +{ + public class ObjectToSerialize + { + public string StringProperty { get; set; } + public int IntProperty { get; set; } + public double DoubleProperty { get; set; } + } + + public interface IPluginWithSerializer + { + string SerializeObject(ObjectToSerialize obj); + } +} diff --git a/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsContract/ITokenService.cs b/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsContract/ITokenService.cs new file mode 100644 index 0000000..39cd1f2 --- /dev/null +++ b/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsContract/ITokenService.cs @@ -0,0 +1,11 @@ +using System.Threading.Tasks; + +namespace Prise.IntegrationTestsContract +{ + public interface ITokenService + { + Task GenerateToken(); + + Task ValidateToken(string token); + } +} diff --git a/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsContract/ITranslationPlugin.cs b/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsContract/ITranslationPlugin.cs new file mode 100644 index 0000000..cf89cf9 --- /dev/null +++ b/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsContract/ITranslationPlugin.cs @@ -0,0 +1,26 @@ +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace Prise.IntegrationTestsContract +{ + public class TranslationInput + { + public string ContentToTranslate { get; set; } + } + + public class TranslationOutput + { + public string Translation { get; set; } + public string ToLanguage { get; set; } + public decimal Accuracy { get; set; } + } + + public interface ITranslationPlugin + { + Task> Translate(TranslationInput input); + } + + public interface ITranslationPlugin2 : ITranslationPlugin + { + } +} diff --git a/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsContract/Prise.IntegrationTestsContract.csproj b/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsContract/Prise.IntegrationTestsContract.csproj new file mode 100644 index 0000000..7f9a1bb --- /dev/null +++ b/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsContract/Prise.IntegrationTestsContract.csproj @@ -0,0 +1,9 @@ + + + + netstandard2.0 + + + + + diff --git a/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsHost/Controllers/CalculationController.cs b/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsHost/Controllers/CalculationController.cs new file mode 100644 index 0000000..d934139 --- /dev/null +++ b/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsHost/Controllers/CalculationController.cs @@ -0,0 +1,41 @@ +using System.Linq; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Logging; + +using Prise.IntegrationTestsHost.Models; +using Prise.IntegrationTestsContract; +using System.Threading.Tasks; +using Prise.IntegrationTestsHost.PluginLoaders; + +namespace Prise.IntegrationTestsHost.Controllers +{ + [ApiController] + [Route("calculation")] + public class CalculationController : CalculationControllerBase + { + private readonly ILogger _logger; + + public CalculationController(ILogger logger, ICalculationPluginLoader loader) : base(loader) + { + _logger = logger; + } + + [HttpPost] + public Task Calculate(CalculationRequestModel requestModel) => base.Calculate(requestModel); + + [HttpPost("int")] + public Task CalculateInt(CalculationRequestModel requestModel) => base.CalculateInt(requestModel); + + [HttpPost("complex-input")] + public Task CalculateComplex(CalculationRequestModel requestModel) => base.CalculateComplex(requestModel); + + [HttpPost("complex-output")] + public Task CalculateComplexOutput(CalculationRequestModel requestModel) => base.CalculateComplexOutput(requestModel); + + [HttpPost("multi")] + public Task CalculateMultiple(CalculationRequestMultiModel requestModel) => base.CalculateMultiple(requestModel); + + [HttpPost("multi-async")] + public Task CalculateMultipleAsync(CalculationRequestMultiModel requestModel) => base.CalculateMultipleAsync(requestModel); + } +} diff --git a/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsHost/Controllers/CalculationControllerBase.cs b/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsHost/Controllers/CalculationControllerBase.cs new file mode 100644 index 0000000..caab489 --- /dev/null +++ b/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsHost/Controllers/CalculationControllerBase.cs @@ -0,0 +1,97 @@ +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; +using Prise.IntegrationTestsContract; +using Prise.IntegrationTestsHost.Models; +using Prise.IntegrationTestsHost.PluginLoaders; + +namespace Prise.IntegrationTestsHost.Controllers +{ + public abstract class CalculationControllerBase : ControllerBase + { + protected ICalculationPluginLoader pluginLoader; + public CalculationControllerBase(ICalculationPluginLoader pluginLoader) + { + this.pluginLoader = pluginLoader; + } + + protected virtual async Task GetCalculationPlugin() + { + return await this.pluginLoader.GetPlugin(); + } + + protected async Task Calculate(CalculationRequestModel requestModel) + { + // The plugin is eagerly loaded (in-scope) + return new CalculationResponseModel + { + Result = (await GetCalculationPlugin()).Calculate(requestModel.A, requestModel.B) + }; + } + + protected async Task CalculateInt(CalculationRequestModel requestModel) + { + // Overloading works due to matching the Proxy on parameter count and types + return new CalculationResponseModel + { + Result = (await GetCalculationPlugin()).Calculate((int)requestModel.A, (int)requestModel.B) + }; + } + + protected async Task CalculateComplex(CalculationRequestModel requestModel) + { + // Complex parameters are serialized across Application Domains using Newtonsoft JSON + var context = new CalculationContext + { + A = requestModel.A, + B = requestModel.B + }; + return new CalculationResponseModel + { + Result = (await GetCalculationPlugin()).CalculateComplex(context) + }; + } + + protected async Task CalculateComplexOutput(CalculationRequestModel requestModel) + { + var context = new CalculationContext + { + A = requestModel.A, + B = requestModel.B + }; + // Complex results are dezerialized using XML Deserialization (by default) + return new CalculationResponseModel + { + Result = (await GetCalculationPlugin()).CalculateComplexResult(context).Result + }; + } + + protected async Task CalculateMultiple(CalculationRequestMultiModel requestModel) + { + // Ever more complex objects are serialized correctly + var calculationContext = new ComplexCalculationContext + { + Calculations = requestModel.Calculations.Select(c => new CalculationContext { A = c.A, B = c.B }).ToArray() + }; + + return new CalculationResponseModel + { + Result = (await GetCalculationPlugin()).CalculateMutiple(calculationContext).Results.Sum(r => r.Result) + }; + } + + protected async Task CalculateMultipleAsync(CalculationRequestMultiModel requestModel) + { + // Ever more complex objects are serialized correctly + var calculationContext = new ComplexCalculationContext + { + Calculations = requestModel.Calculations.Select(c => new CalculationContext { A = c.A, B = c.B }).ToArray() + }; + + return new CalculationResponseModel + { + Result = (await (await GetCalculationPlugin()).CalculateMutipleAsync(calculationContext)).Results.Sum(r => r.Result) + }; + } + } +} diff --git a/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsHost/Controllers/DiscoveryController.cs b/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsHost/Controllers/DiscoveryController.cs new file mode 100644 index 0000000..338d350 --- /dev/null +++ b/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsHost/Controllers/DiscoveryController.cs @@ -0,0 +1,43 @@ +using System.Linq; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Logging; + +using Prise.IntegrationTestsHost.PluginLoaders; +using Prise.IntegrationTestsHost.Models; +using Prise.IntegrationTestsContract; +using Prise.Infrastructure; +using System.Text; +using System.Threading.Tasks; + +namespace Prise.IntegrationTestsHost.Controllers +{ + [ApiController] + [Route("disco")] + public class DiscoveryController : ControllerBase + { + private readonly ILogger logger; + private readonly ICalculationPluginLoader loader; + + public DiscoveryController(ILogger logger, ICalculationPluginLoader loader) + { + this.logger = logger; + this.loader = loader; + } + + [HttpGet] + public async Task DiscoverPlugins() + { + var plugins = await this.loader.GetPlugins(); + + return string.Join(',', plugins.Select(p => p.Name)); + } + + [HttpGet("description")] + public async Task DiscoverPluginsWithDescription() + { + var plugins = await this.loader.GetPlugins(); + + return string.Join(',', plugins.Select(p => p.Description)); + } + } +} diff --git a/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsHost/Controllers/MultipleCalculationController.cs b/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsHost/Controllers/MultipleCalculationController.cs new file mode 100644 index 0000000..a953602 --- /dev/null +++ b/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsHost/Controllers/MultipleCalculationController.cs @@ -0,0 +1,35 @@ +using System.Collections.Generic; +using System.Linq; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Logging; +using Prise.IntegrationTestsContract; +using Prise.IntegrationTestsHost.PluginLoaders; +using Prise.IntegrationTestsHost.Models; +using System.Threading.Tasks; + +namespace Prise.IntegrationTestsHost.Controllers +{ + [ApiController] + [Route("multiple")] + public class MultipleCalculationController + { + private readonly ILogger logger; + private readonly ICalculationPluginLoader loader; + + public MultipleCalculationController(ILogger logger, ICalculationPluginLoader loader) + { + this.logger = logger; + this.loader = loader; + } + + [HttpPost] + public async Task Calculate(CalculationRequestModel requestModel) + { + var plugins = await this.loader.GetPlugins(); + return new CalculationResponseModel + { + Result = plugins.Sum(p => p.Calculate(requestModel.A, requestModel.B)) + }; + } + } +} \ No newline at end of file diff --git a/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsHost/Custom/AppHostFrameworkProvider.cs b/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsHost/Custom/AppHostFrameworkProvider.cs new file mode 100644 index 0000000..361b362 --- /dev/null +++ b/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsHost/Custom/AppHostFrameworkProvider.cs @@ -0,0 +1,20 @@ +using System.Reflection; +using System.Runtime.Versioning; + +namespace Prise.IntegrationTestsHost +{ + public interface IHostFrameworkProvider + { + string ProvideHostFramework(); + } + + /// + /// This is required for testing + /// + public class AppHostFrameworkProvider : IHostFrameworkProvider + { + public string ProvideHostFramework() => typeof(AppHostFrameworkProvider).Assembly + .GetCustomAttribute()? + .FrameworkName; + } +} \ No newline at end of file diff --git a/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsHost/ICommandLineArguments.cs b/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsHost/ICommandLineArguments.cs new file mode 100644 index 0000000..571cf7f --- /dev/null +++ b/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsHost/ICommandLineArguments.cs @@ -0,0 +1,39 @@ +using Microsoft.Extensions.Configuration; + +namespace Prise.IntegrationTestsHost +{ + public interface ICommandLineArguments + { + bool UseLazyService { get; } + bool UseCollectibleAssemblies { get; } + } + + public class CommandLineArguments : ICommandLineArguments + { + private readonly IConfiguration config; + public CommandLineArguments(IConfiguration config) + { + this.config = config; + } + + public bool UseLazyService + { + get + { + if (bool.TryParse(this.config["uselazyservice"], out var uselazyservice)) + return uselazyservice; + return false; + } + } + + public bool UseCollectibleAssemblies + { + get + { + if (bool.TryParse(this.config["usecollectibleassemblies"], out var usecollectibleassemblies)) + return usecollectibleassemblies; + return false; + } + } + } +} \ No newline at end of file diff --git a/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsHost/Models/CalculationRequestModel.cs b/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsHost/Models/CalculationRequestModel.cs new file mode 100644 index 0000000..92967a7 --- /dev/null +++ b/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsHost/Models/CalculationRequestModel.cs @@ -0,0 +1,8 @@ +namespace Prise.IntegrationTestsHost.Models +{ + public class CalculationRequestModel + { + public decimal A { get; set; } + public decimal B { get; set; } + } +} \ No newline at end of file diff --git a/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsHost/Models/CalculationRequestMultiModel.cs b/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsHost/Models/CalculationRequestMultiModel.cs new file mode 100644 index 0000000..66724b0 --- /dev/null +++ b/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsHost/Models/CalculationRequestMultiModel.cs @@ -0,0 +1,7 @@ +namespace Prise.IntegrationTestsHost.Models +{ + public class CalculationRequestMultiModel + { + public CalculationRequestModel[] Calculations{get;set;} + } +} \ No newline at end of file diff --git a/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsHost/Models/CalculationResponseModel.cs b/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsHost/Models/CalculationResponseModel.cs new file mode 100644 index 0000000..92e70da --- /dev/null +++ b/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsHost/Models/CalculationResponseModel.cs @@ -0,0 +1,7 @@ +namespace Prise.IntegrationTestsHost.Models +{ + public class CalculationResponseModel + { + public decimal Result {get;set;} + } +} \ No newline at end of file diff --git a/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsHost/PluginLoaders/CalculationPluginLoader.cs b/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsHost/PluginLoaders/CalculationPluginLoader.cs new file mode 100644 index 0000000..59f3bc2 --- /dev/null +++ b/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsHost/PluginLoaders/CalculationPluginLoader.cs @@ -0,0 +1,59 @@ +using Microsoft.AspNetCore.Http; +using Prise.IntegrationTestsContract; +using System.Threading.Tasks; +using System.Collections.Generic; +using System.Reflection; +using System.Linq; +using System.IO; +using System; +using Prise; + +namespace Prise.IntegrationTestsHost.PluginLoaders +{ + public interface ICalculationPluginLoader + { + Task GetPlugin(); + Task> GetPlugins(); + } + + public class CalculationPluginLoader : ICalculationPluginLoader + { + private readonly IPluginLoader pluginLoader; + private readonly IHttpContextAccessor httpContextAccessor; + private readonly string pluginBaseDir = Path.GetFullPath("../../../../_dist", AppDomain.CurrentDomain.BaseDirectory); + + public CalculationPluginLoader(IPluginLoader pluginLoader, IHttpContextAccessor httpContextAccessor) + { + this.pluginLoader = pluginLoader; + this.httpContextAccessor = httpContextAccessor; + } + + public async Task GetPlugin() + { + var pluginType = this.httpContextAccessor.HttpContext.Request.Headers["PluginType"].First(); + var plugins = await this.pluginLoader.FindPlugins(Path.Combine(this.pluginBaseDir, pluginType)); + + var firstPlugin = plugins.First(); + return await this.pluginLoader.LoadPlugin(firstPlugin, configure: (ctx) => + { + // ctx. + }); + } + + public async Task> GetPlugins() + { + var pluginType = this.httpContextAccessor.HttpContext.Request.Headers["PluginType"].First(); + var plugins = await this.pluginLoader.FindPlugins(Path.Combine(this.pluginBaseDir, pluginType)); + + var instances = new List(); + foreach (var plugin in plugins) + { + instances.Add(await this.pluginLoader.LoadPlugin(plugin, configure: (ctx) => + { + // ctx. + })); + } + return instances; + } + } +} \ No newline at end of file diff --git a/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsHost/Prise.IntegrationTestsHost.csproj b/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsHost/Prise.IntegrationTestsHost.csproj new file mode 100644 index 0000000..f6e78b5 --- /dev/null +++ b/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsHost/Prise.IntegrationTestsHost.csproj @@ -0,0 +1,49 @@ + + + + net6.0 + + + + NETCORE2_1 + + + NETCORE3_1 + + + NETCORE3_1 + + + NETCORE3_1 + + + + + + + + + + + + + + + + Always + + + Always + + + Always + + + Always + + + Always + + + + diff --git a/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsHost/Program.cs b/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsHost/Program.cs new file mode 100644 index 0000000..b184023 --- /dev/null +++ b/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsHost/Program.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; + +namespace Prise.IntegrationTestsHost +{ + public partial class Program + { + public static void Main(string[] args) + { +#if NETCORE3_1 + CreateHostBuilder(args).Build().Run(); + +#endif +#if NETCORE2_1 + CreateWebHostBuilder(args).Build().Run(); +#endif + } + } +} diff --git a/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsHost/Program.netcore2.cs b/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsHost/Program.netcore2.cs new file mode 100644 index 0000000..02a78ae --- /dev/null +++ b/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsHost/Program.netcore2.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; + +namespace Prise.IntegrationTestsHost +{ + public partial class Program + { + +#if NETCORE2_1 + public static IWebHostBuilder CreateWebHostBuilder(string[] args) + { + var consoleConfig = new ConfigurationBuilder() + .AddCommandLine(args) + .Build(); + + return WebHost.CreateDefaultBuilder(args) + .ConfigureServices(services => + { + services.AddSingleton(new CommandLineArguments(consoleConfig)); + }) + .UseStartup() + .UseUrls("http://localhost:5003"); + } +#endif + } +} diff --git a/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsHost/Program.netcore3.cs b/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsHost/Program.netcore3.cs new file mode 100644 index 0000000..8918d20 --- /dev/null +++ b/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsHost/Program.netcore3.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; + +namespace Prise.IntegrationTestsHost +{ + public partial class Program + { +#if NETCORE3_1 + public static IHostBuilder CreateHostBuilder(string[] args) + { + var consoleConfig = new ConfigurationBuilder() + .AddCommandLine(args) + .Build(); + + return Host.CreateDefaultBuilder(args) + .ConfigureServices((hostContext, services) => + services.AddSingleton(new CommandLineArguments(consoleConfig))) + .ConfigureWebHostDefaults(webBuilder => + { + webBuilder + .UseStartup() + .UseUrls("http://localhost:5003"); + }); + } +#endif + } +} diff --git a/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsHost/Properties/launchSettings.json b/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsHost/Properties/launchSettings.json new file mode 100644 index 0000000..cb5b8e6 --- /dev/null +++ b/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsHost/Properties/launchSettings.json @@ -0,0 +1,30 @@ +{ + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:12043", + "sslPort": 44300 + } + }, + "$schema": "http://json.schemastore.org/launchsettings.json", + "profiles": { + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "launchUrl": "weatherforecast", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "Prise.IntegrationTestsHost": { + "commandName": "Project", + "commandLineArgs": "usecollectibleassemblies=false", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "applicationUrl": "https://localhost:5001;http://localhost:5000" + } + } +} \ No newline at end of file diff --git a/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsHost/Services/ICalculationService.cs b/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsHost/Services/ICalculationService.cs new file mode 100644 index 0000000..0ebcd47 --- /dev/null +++ b/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsHost/Services/ICalculationService.cs @@ -0,0 +1,163 @@ +using System.Linq; +using System.Threading.Tasks; +using Prise.IntegrationTestsContract; +using Prise.IntegrationTestsHost.Models; +using Prise.Infrastructure; + +namespace Prise.IntegrationTestsHost.Services +{ + public interface ICalculationService + { + Task Calculate(CalculationRequestModel requestModel); + Task CalculateInt(CalculationRequestModel requestModel); + Task CalculateComplex(CalculationRequestModel requestModel); + Task CalculateComplexOutput(CalculationRequestModel requestModel); + Task CalculateMultiple(CalculationRequestMultiModel requestModel); + } + + // public class EagerCalculationService : ICalculationService + // { + // private readonly ICalculationPlugin _plugin; + + // // An instance of the plugin is injected in this service + // public EagerCalculationService(ICalculationPlugin plugin) + // { + // this._plugin = plugin; + // } + + // public Task Calculate(CalculationRequestModel requestModel) + // { + // // The plugin is eagerly loaded (in-scope) + // return Task.FromResult(new CalculationResponseModel + // { + // Result = _plugin.Calculate(requestModel.A, requestModel.B) + // }); + // } + + // public Task CalculateInt(CalculationRequestModel requestModel) + // { + // // Overloading works due to matching the Proxy on parameter count and types + // return Task.FromResult(new CalculationResponseModel + // { + // Result = _plugin.Calculate((int)requestModel.A, (int)requestModel.B) + // }); + // } + + // public Task CalculateComplex(CalculationRequestModel requestModel) + // { + // // Complex parameters are serialized across Application Domains using Newtonsoft JSON + // var context = new CalculationContext + // { + // A = requestModel.A, + // B = requestModel.B + // }; + // return Task.FromResult(new CalculationResponseModel + // { + // Result = _plugin.CalculateComplex(context) + // }); + // } + + // public Task CalculateComplexOutput(CalculationRequestModel requestModel) + // { + // var context = new CalculationContext + // { + // A = requestModel.A, + // B = requestModel.B + // }; + // // Complex results are dezerialized using XML Deserialization (by default) + // return Task.FromResult(new CalculationResponseModel + // { + // Result = _plugin.CalculateComplexResult(context).Result + // }); + // } + + // public Task CalculateMultiple(CalculationRequestMultiModel requestModel) + // { + // // Ever more complex objects are serialized correctly + // var calculationContext = new ComplexCalculationContext + // { + // Calculations = requestModel.Calculations.Select(c => new CalculationContext { A = c.A, B = c.B }).ToArray() + // }; + + // return Task.FromResult(new CalculationResponseModel + // { + // Result = _plugin.CalculateMutiple(calculationContext).Results.Sum(r => r.Result) + // }); + // } + // } + + // public class LazyCalculationService : ICalculationService + // { + // private readonly IPluginLoader loader; + + // public LazyCalculationService(IPluginLoader loader) + // { + // this.loader = loader; + // } + + // public async Task Calculate(CalculationRequestModel requestModel) + // { + // var _plugin = await loader.Load(); + // // The plugin is eagerly loaded (in-scope) + // return new CalculationResponseModel + // { + // Result = _plugin.Calculate(requestModel.A, requestModel.B) + // }; + // } + + // public async Task CalculateInt(CalculationRequestModel requestModel) + // { + // var _plugin = await loader.Load(); + // // Overloading works due to matching the Proxy on parameter count and types + // return new CalculationResponseModel + // { + // Result = _plugin.Calculate((int)requestModel.A, (int)requestModel.B) + // }; + // } + + // public async Task CalculateComplex(CalculationRequestModel requestModel) + // { + // var _plugin = await loader.Load(); + // // Complex parameters are serialized across Application Domains using Newtonsoft JSON + // var context = new CalculationContext + // { + // A = requestModel.A, + // B = requestModel.B + // }; + // return new CalculationResponseModel + // { + // Result = _plugin.CalculateComplex(context) + // }; + // } + + // public async Task CalculateComplexOutput(CalculationRequestModel requestModel) + // { + // var _plugin = await loader.Load(); + // var context = new CalculationContext + // { + // A = requestModel.A, + // B = requestModel.B + // }; + // // Complex results are dezerialized using XML Deserialization (by default) + // return new CalculationResponseModel + // { + // Result = _plugin.CalculateComplexResult(context).Result + // }; + // } + + // public async Task CalculateMultiple(CalculationRequestMultiModel requestModel) + // { + // var _plugin = await loader.Load(); + // // Ever more complex objects are serialized correctly + // var calculationContext = new ComplexCalculationContext + // { + // Calculations = requestModel.Calculations.Select(c => new CalculationContext { A = c.A, B = c.B }).ToArray() + // }; + + // return new CalculationResponseModel + // { + // Result = _plugin.CalculateMutiple(calculationContext).Results.Sum(r => r.Result) + // }; + // } + // } +} \ No newline at end of file diff --git a/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsHost/Startup.cs b/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsHost/Startup.cs new file mode 100644 index 0000000..989affa --- /dev/null +++ b/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsHost/Startup.cs @@ -0,0 +1,85 @@ +using System.IO; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Microsoft.AspNetCore.Mvc; + +using Prise.DependencyInjection; +using Prise.IntegrationTestsContract; +using Prise.IntegrationTestsHost.Services; +using System; +using Microsoft.AspNetCore.StaticFiles; +using Microsoft.Extensions.FileProviders; +using Prise.IntegrationTestsHost.Controllers; +using Prise.IntegrationTestsHost.PluginLoaders; +using System.Reflection; +using System.Runtime.Versioning; + +namespace Prise.IntegrationTestsHost +{ + public partial class Startup + { + public Startup(IConfiguration configuration) + { + Configuration = configuration; + } + + public IConfiguration Configuration { get; } + // This method gets called by the runtime. Use this method to add services to the container. + public void ConfigureServices(IServiceCollection services) + { + ConfigureTargetFramework(services); + + services.AddHttpClient(); + services.AddHttpContextAccessor(); + services.AddTransient(); + services.AddPrise(); + + AddPriseCalculationPlugins(services); + } + + protected virtual IServiceCollection AddPriseCalculationPlugins(IServiceCollection services) + { + return services.AddTransient(); + } + + // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. +#if NETCORE3_1 + public void Configure(IApplicationBuilder app, IWebHostEnvironment env) +#endif +#if NETCORE2_1 + public void Configure(IApplicationBuilder app, Microsoft.AspNetCore.Hosting.IHostingEnvironment env) +#endif + { + if (env.IsDevelopment()) + { + app.UseDeveloperExceptionPage(); + } + + app.UseHttpsRedirection(); + + ConfigureTargetFramework(app); + + // var provider = new FileExtensionContentTypeProvider(); + // // Add new mappings + // provider.Mappings[".dll"] = "application/x-msdownload"; + // app.UseStaticFiles(new StaticFileOptions + // { + // ServeUnknownFileTypes = true, + // FileProvider = new PhysicalFileProvider( + // Path.Combine(Directory.GetCurrentDirectory(), "Plugins")), + // RequestPath = "/Plugins", + // ContentTypeProvider = provider + // }); + + // app.UseDirectoryBrowser(new DirectoryBrowserOptions + // { + // FileProvider = new PhysicalFileProvider( + // Path.Combine(Directory.GetCurrentDirectory(), "Plugins")), + // RequestPath = "/Plugins" + // }); + } + } +} diff --git a/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsHost/Startup.netcore2.cs b/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsHost/Startup.netcore2.cs new file mode 100644 index 0000000..3fa0e26 --- /dev/null +++ b/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsHost/Startup.netcore2.cs @@ -0,0 +1,33 @@ +using System.IO; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Microsoft.AspNetCore.Mvc; + +using Prise; +using Prise.IntegrationTestsContract; +using Prise.IntegrationTestsHost.Services; +using System; + +namespace Prise.IntegrationTestsHost +{ + public partial class Startup + { +#if NETCORE2_1 + private void ConfigureTargetFramework(IServiceCollection services) + { + services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1); + } +#endif + + // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. +#if NETCORE2_1 + private void ConfigureTargetFramework(IApplicationBuilder app) + { + app.UseMvc(); + } +#endif + } +} diff --git a/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsHost/Startup.netcore3.cs b/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsHost/Startup.netcore3.cs new file mode 100644 index 0000000..70e0785 --- /dev/null +++ b/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsHost/Startup.netcore3.cs @@ -0,0 +1,38 @@ +using System.IO; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Microsoft.AspNetCore.Mvc; + +using Prise; +using Prise.IntegrationTestsContract; +using Prise.IntegrationTestsHost.Services; +using System; + +namespace Prise.IntegrationTestsHost +{ + public partial class Startup + { +#if NETCORE3_1 + private void ConfigureTargetFramework(IServiceCollection services) + { + services.AddControllers(); + services.AddDirectoryBrowser(); + } +#endif + + // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. +#if NETCORE3_1 + private void ConfigureTargetFramework(IApplicationBuilder app) + { + app.UseRouting(); + app.UseEndpoints(endpoints => + { + endpoints.MapControllers(); + }); + } +#endif + } +} diff --git a/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsHost/appsettings.json b/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsHost/appsettings.json new file mode 100644 index 0000000..56cc9b5 --- /dev/null +++ b/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsHost/appsettings.json @@ -0,0 +1,12 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft": "Warning", + "Microsoft.Hosting.Lifetime": "Information" + } + }, + "AllowedHosts": "*", + "DivideOrMultiply": "MultiplyCalculation", // MultiplyCalculation or DivideCalculation + "LanguageOverride": "" +} diff --git a/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsHost/data.json b/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsHost/data.json new file mode 100644 index 0000000..8bdc6ed --- /dev/null +++ b/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsHost/data.json @@ -0,0 +1,29 @@ +[ + { + "id": 1, + "name": "Test", + "amount": 15.55, + "children": [ + { + "id": 10, + "name": "Test10", + "amount": 15.55 + }, + { + "id": 11, + "name": "Test11", + "amount": 15.55 + }, + { + "id": 12, + "name": "Test12", + "amount": 15.55 + } + ] + }, + { + "id": 1, + "name": "Test", + "amount": 15.55 + } +] \ No newline at end of file diff --git a/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsHost/dictionary-de-DE.json b/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsHost/dictionary-de-DE.json new file mode 100644 index 0000000..cfe9357 --- /dev/null +++ b/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsHost/dictionary-de-DE.json @@ -0,0 +1,7 @@ +{ + "dog": "Hund", + "doge": "Hund Meme", + "cat": "Katze", + "hello": "Guten Tag", + "goodbye": "Auf Wiedersehen" +} \ No newline at end of file diff --git a/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsHost/dictionary-fr-FR.json b/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsHost/dictionary-fr-FR.json new file mode 100644 index 0000000..04b6885 --- /dev/null +++ b/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsHost/dictionary-fr-FR.json @@ -0,0 +1,7 @@ +{ + "dog": "Chien", + "doge": "Chien de Meme", + "cat": "Chat", + "hello": "Bonjour", + "goodbye": "Au revoir" +} \ No newline at end of file diff --git a/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsHost/dictionary-nl-BE.json b/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsHost/dictionary-nl-BE.json new file mode 100644 index 0000000..44d01a1 --- /dev/null +++ b/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsHost/dictionary-nl-BE.json @@ -0,0 +1,7 @@ +{ + "dog": "Hond", + "doge": "Hond van de meme", + "cat": "Kat", + "hello": "Hallo", + "goodbye": "Tot ziens" +} \ No newline at end of file diff --git a/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsHost/http/Calculations.http b/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsHost/http/Calculations.http new file mode 100644 index 0000000..6541bf3 --- /dev/null +++ b/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsHost/http/Calculations.http @@ -0,0 +1,9 @@ +POST http://localhost:5003/calculation +Content-Type: application/json +# PluginType: PluginA +PluginType: PluginC + +{ + "a":1, + "b":2 +} \ No newline at end of file diff --git a/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsHost/http/Disco.http b/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsHost/http/Disco.http new file mode 100644 index 0000000..f7bd071 --- /dev/null +++ b/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsHost/http/Disco.http @@ -0,0 +1,4 @@ +GET http://localhost:5003/disco +Content-Type: application/json +# PluginType: PluginA +PluginType: PluginA \ No newline at end of file diff --git a/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsHost/tokens.json b/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsHost/tokens.json new file mode 100644 index 0000000..28c74a7 --- /dev/null +++ b/Vendor/Prise.Tests.Integration/Prise.IntegrationTestsHost/tokens.json @@ -0,0 +1,12 @@ +[ + "09133725-bf24-48b8-9ca8-998e867360e6", + "766b827e-42bd-4a88-a3c2-0448f92e60cb", + "e7324dce-aabb-4d23-9771-ca8e40add367", + "2878b023-2ec7-422f-bbe5-97b8d2600d58", + "34feccd0-6464-4e81-99ae-5d4f2bd6a160", + "4173bf53-4f9c-4fe8-848d-c622941944fb", + "2d2e33d6-8c45-4441-95fd-c237af13458f", + "8d1810ec-8880-4c98-ad08-8265c4b9ed18", + "7992633e-80f5-4cc8-9dde-1196e4c801e4", + "095124b2-aac5-4ea2-a6e8-f3305e4a246c" +] \ No newline at end of file diff --git a/Vendor/Prise.Tests.Integration/build.cake b/Vendor/Prise.Tests.Integration/build.cake new file mode 100644 index 0000000..af21659 --- /dev/null +++ b/Vendor/Prise.Tests.Integration/build.cake @@ -0,0 +1,197 @@ +var target = Argument("target", "default"); +var configuration = Argument("configuration", "Debug"); +var plugins = new[] { + "LegacyPlugin1.4", + "LegacyPlugin1.5", + "PluginA", + "PluginB", + "PluginC", + "PluginCFromNetwork", + "PluginD", + "PluginDWithFactory", + "PluginE", + "PluginF", + "PluginG" +}; +var networkPlugins = new[] { "PluginCFromNetwork" }; + +public string[] GetPublishedPlugins(string target){ + var path = System.IO.Path.Combine($"publish", $"{target}"); + if(System.IO.Directory.Exists(path)) + return System.IO.Directory.GetDirectories(path); + return new string[0]; +} + +public string[] GetAllProjectsFromPluginDir(string dir) +{ + return System.IO.Directory.GetFiles(dir, "*.csproj"); +} + +public string GetNuspecFileForProject(string project) +{ + var dir = System.IO.Path.GetDirectoryName(project); + var projectNameWithoutExtension = System.IO.Path.GetFileNameWithoutExtension(project); + var nuspecs = System.IO.Directory.GetFiles(dir, "*.nuspec"); + + return nuspecs.FirstOrDefault(n => System.IO.Path.GetFileNameWithoutExtension(n) == projectNameWithoutExtension); +} + +public string GetTargetFrameworkFromProject(string project) +{ + var targetFramework = System.Xml.Linq.XDocument.Load(project).Root.DescendantNodes().OfType() + .FirstOrDefault(x => x.Name.LocalName.Equals("TargetFramework")); + + return targetFramework?.Value; +} + +private void CleanProject(string projectDirectory, string projectFile){ + var bin = System.IO.Path.Combine($"IntegrationTestsPlugins", $"{projectDirectory}", "bin"); + var obj = System.IO.Path.Combine($"IntegrationTestsPlugins", $"{projectDirectory}", "obj"); + + var deleteSettings = new DeleteDirectorySettings{ + Force= true, + Recursive = true + }; + + var cleanSettings = new DotNetCoreCleanSettings + { + Configuration = configuration + }; + if (DirectoryExists(bin)) + { + DeleteDirectory(bin, deleteSettings); + } + if (DirectoryExists(obj)) + { + DeleteDirectory(obj, deleteSettings); + } + DotNetCoreClean(projectFile, cleanSettings); +} + +Task("clean") + .Does( () => + { + foreach (var plugin in plugins) + { + var projects = GetAllProjectsFromPluginDir($"IntegrationTestsPlugins/{plugin}"); + foreach (var project in projects) + CleanProject(plugin, project); + } + }); + +Task("clean-published") + .Does( () => + { + var deleteSettings = new DeleteDirectorySettings{ + Force= true, + Recursive = true + }; + DeleteDirectory("publish", deleteSettings); + DeleteDirectory(System.IO.Path.Combine($"Prise.IntegrationTests", "bin", "debug","netcoreapp2.1","Plugins"), deleteSettings); + DeleteDirectory(System.IO.Path.Combine($"Prise.IntegrationTestsHost", "bin", "debug","netcoreapp2.1","Plugins"), deleteSettings); + DeleteDirectory(System.IO.Path.Combine($"Prise.IntegrationTests", "bin", "debug","netcoreapp3.0","Plugins"), deleteSettings); + DeleteDirectory(System.IO.Path.Combine($"Prise.IntegrationTestsHost", "bin", "debug","netcoreapp3.0","Plugins"), deleteSettings); + DeleteDirectory(System.IO.Path.Combine($"Prise.IntegrationTests", "bin", "debug","netcoreapp3.1","Plugins"), deleteSettings); + DeleteDirectory(System.IO.Path.Combine($"Prise.IntegrationTestsHost", "bin", "debug","netcoreapp3.1","Plugins"), deleteSettings); + }); + +private void FixAssemblyIssues(string pathToDlls) +{ + using(var process = StartAndReturnProcess("dotnet", + new ProcessSettings{ Arguments = $"{System.IO.Path.Combine("FileBulkDateChanger", "FileBulkDateChanger.dll")} {pathToDlls}"})) + { + process.WaitForExit(2000);//Waits for 2 seconds + } +} + +Task("publish") + .IsDependentOn("clean") + .Does(() => + { + foreach (var plugin in plugins) + { + var projects = GetAllProjectsFromPluginDir(System.IO.Path.Combine("IntegrationTestsPlugins", $"{plugin}")); + foreach (var project in projects) + { + var targetFramework = GetTargetFrameworkFromProject(project); + var nuspecForProject = GetNuspecFileForProject(project); + var outputDir = System.IO.Path.Combine("publish", $"{targetFramework}", $"{plugin}"); + if(nuspecForProject!= null) + outputDir = null; + + DotNetCorePublish(project, new DotNetCorePublishSettings + { + NoBuild = false, + Configuration = configuration, + Framework = targetFramework, + OutputDirectory = outputDir + }); + + if(nuspecForProject!= null){ + FixAssemblyIssues(System.IO.Path.Combine($"IntegrationTestsPlugins", $"{plugin}", "bin", $"{configuration}", $"{targetFramework}", "publish")); + var nuspecFilename = System.IO.Path.GetFileName(nuspecForProject); + DotNetCorePack(project, new DotNetCorePackSettings + { + NoBuild = true, + Configuration = configuration, + OutputDirectory = System.IO.Path.Combine($"publish", $"{targetFramework}"), + ArgumentCustomization = (args) => args.Append($"/p:nuspecfile={nuspecFilename}") + }); + } + } + } +}); + +private void CopyToTestHosts(string dir, params string[] frameworks){ + var publishDir = System.IO.Path.GetDirectoryName(dir); // last directory in path: x/y/z => z + var pluginDir = System.IO.Path.GetFileName(dir); // last directory in path: x/y/z => z + foreach(var fwk in frameworks){ + CopyDirectory(dir, System.IO.Path.Combine($"Prise.IntegrationTests", "bin", "debug", fwk, "Plugins", pluginDir)); + CopyDirectory(dir, System.IO.Path.Combine($"Prise.IntegrationTestsHost", "bin", "debug", fwk, "Plugins", pluginDir)); + } +} + +Task("copy-to-testhosts") + .IsDependentOn("publish") + .Does(() => + { + foreach(var netstandard20 in GetPublishedPlugins("netstandard2.0")){ + Console.WriteLine(netstandard20); + if(System.IO.Directory.Exists(netstandard20)) + CopyToTestHosts(netstandard20, "netcoreapp2.1", "netcoreapp3.0", "netcoreapp3.1"); + } + foreach(var netstandard21 in GetPublishedPlugins("netstandard2.1")){ + if(System.IO.Directory.Exists(netstandard21)) + CopyToTestHosts(netstandard21, "netcoreapp2.1", "netcoreapp3.0", "netcoreapp3.1"); + } + foreach(var netcoreapp21 in GetPublishedPlugins("netcoreapp2.1")){ + if(System.IO.Directory.Exists(netcoreapp21)) + CopyToTestHosts(netcoreapp21, "netcoreapp2.1", "netcoreapp3.0", "netcoreapp3.1"); + } + foreach(var netcoreapp30 in GetPublishedPlugins("netcoreapp3.0")){ + if(System.IO.Directory.Exists(netcoreapp30)) + CopyToTestHosts(netcoreapp30, "netcoreapp3.0", "netcoreapp3.1"); + } + foreach(var netcoreapp31 in GetPublishedPlugins("netcoreapp3.1")){ + if(System.IO.Directory.Exists(netcoreapp31)) + CopyToTestHosts(netcoreapp31, "netcoreapp3.1"); + } + + foreach(var publishTarget in new[] { "netstandard2.0", "netstandard2.1", "netcoreapp2.1", "netcoreapp3.0", "netcoreapp3.1"}){ + var directory = System.IO.Path.Combine($"publish", $"{publishTarget}"); + if(!System.IO.Directory.Exists(directory)) + continue; + + var packages = System.IO.Directory.GetFiles(directory, "*.nupkg"); + foreach(var package in packages) + foreach(var fwk in new[] {"netcoreapp2.1", "netcoreapp3.0", "netcoreapp3.1"}){ + CopyFiles(package, System.IO.Path.Combine($"Prise.IntegrationTests", "bin", "debug", fwk, "Plugins")); + CopyFiles(package, System.IO.Path.Combine($"Prise.IntegrationTestsHost", "bin", "debug", fwk, "Plugins")); + } + } + }); + +Task("default") + .IsDependentOn("copy-to-testhosts"); + +RunTarget(target); \ No newline at end of file diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginD/Dictionary.Domain.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginD/Dictionary.Domain.dll new file mode 100644 index 0000000..e12c845 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginD/Dictionary.Domain.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginD/Dictionary.Domain.pdb b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginD/Dictionary.Domain.pdb new file mode 100644 index 0000000..cd2548b Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginD/Dictionary.Domain.pdb differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginD/ExternalServiceForPluginD.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginD/ExternalServiceForPluginD.dll new file mode 100644 index 0000000..862ad25 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginD/ExternalServiceForPluginD.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginD/ExternalServiceForPluginD.pdb b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginD/ExternalServiceForPluginD.pdb new file mode 100644 index 0000000..86d43a3 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginD/ExternalServiceForPluginD.pdb differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginD/Microsoft.Extensions.Configuration.Abstractions.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginD/Microsoft.Extensions.Configuration.Abstractions.dll new file mode 100644 index 0000000..80d73ed Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginD/Microsoft.Extensions.Configuration.Abstractions.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginD/Microsoft.Extensions.DependencyInjection.Abstractions.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginD/Microsoft.Extensions.DependencyInjection.Abstractions.dll new file mode 100644 index 0000000..e557f9d Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginD/Microsoft.Extensions.DependencyInjection.Abstractions.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginD/Microsoft.Extensions.DependencyInjection.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginD/Microsoft.Extensions.DependencyInjection.dll new file mode 100644 index 0000000..fc9b787 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginD/Microsoft.Extensions.DependencyInjection.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginD/Microsoft.Extensions.Primitives.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginD/Microsoft.Extensions.Primitives.dll new file mode 100644 index 0000000..1999bac Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginD/Microsoft.Extensions.Primitives.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginD/Newtonsoft.Json.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginD/Newtonsoft.Json.dll new file mode 100644 index 0000000..e2118f9 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginD/Newtonsoft.Json.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginD/PluginD.deps.json b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginD/PluginD.deps.json new file mode 100644 index 0000000..80fb9cd --- /dev/null +++ b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginD/PluginD.deps.json @@ -0,0 +1,198 @@ +{ + "runtimeTarget": { + "name": ".NETCoreApp,Version=v2.1", + "signature": "" + }, + "compilationOptions": {}, + "targets": { + ".NETCoreApp,Version=v2.1": { + "PluginD/1.0.0": { + "dependencies": { + "Dictionary.Domain": "1.0.0", + "ExternalServiceForPluginD": "1.0.0", + "Microsoft.Extensions.Configuration.Abstractions": "2.1.1", + "Prise.IntegrationTestsContract": "1.0.0", + "Prise.Plugin": "1.0.0", + "Prise.PluginBridge": "1.0.0" + }, + "runtime": { + "PluginD.dll": {} + } + }, + "Microsoft.Extensions.Configuration.Abstractions/2.1.1": { + "dependencies": { + "Microsoft.Extensions.Primitives": "2.1.1" + }, + "runtime": { + "lib/netstandard2.0/Microsoft.Extensions.Configuration.Abstractions.dll": { + "assemblyVersion": "2.1.1.0", + "fileVersion": "2.1.1.18157" + } + } + }, + "Microsoft.Extensions.DependencyInjection/2.1.0": { + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "2.1.0" + }, + "runtime": { + "lib/netcoreapp2.0/Microsoft.Extensions.DependencyInjection.dll": { + "assemblyVersion": "2.1.0.0", + "fileVersion": "2.1.0.18136" + } + } + }, + "Microsoft.Extensions.DependencyInjection.Abstractions/2.1.0": { + "runtime": { + "lib/netstandard2.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll": { + "assemblyVersion": "2.1.0.0", + "fileVersion": "2.1.0.18136" + } + } + }, + "Microsoft.Extensions.Primitives/2.1.1": { + "dependencies": { + "System.Memory": "4.5.1", + "System.Runtime.CompilerServices.Unsafe": "4.5.1" + }, + "runtime": { + "lib/netstandard2.0/Microsoft.Extensions.Primitives.dll": { + "assemblyVersion": "2.1.1.0", + "fileVersion": "2.1.1.18157" + } + } + }, + "Newtonsoft.Json/11.0.2": { + "runtime": { + "lib/netstandard2.0/Newtonsoft.Json.dll": { + "assemblyVersion": "11.0.0.0", + "fileVersion": "11.0.2.21924" + } + } + }, + "System.Memory/4.5.1": {}, + "System.Runtime.CompilerServices.Unsafe/4.5.1": { + "runtime": { + "lib/netcoreapp2.0/System.Runtime.CompilerServices.Unsafe.dll": { + "assemblyVersion": "4.0.4.0", + "fileVersion": "0.0.0.0" + } + } + }, + "Dictionary.Domain/1.0.0": { + "dependencies": { + "Newtonsoft.Json": "11.0.2" + }, + "runtime": { + "Dictionary.Domain.dll": {} + } + }, + "ExternalServiceForPluginD/1.0.0": { + "runtime": { + "ExternalServiceForPluginD.dll": {} + } + }, + "Prise.IntegrationTestsContract/1.0.0": { + "runtime": { + "Prise.IntegrationTestsContract.dll": {} + } + }, + "Prise.Plugin/1.0.0": { + "dependencies": { + "Microsoft.Extensions.DependencyInjection": "2.1.0" + }, + "runtime": { + "Prise.Plugin.net2.dll": {} + } + }, + "Prise.PluginBridge/1.0.0": { + "dependencies": { + "Newtonsoft.Json": "11.0.2" + }, + "runtime": { + "Prise.PluginBridge.net2.dll": {} + } + } + } + }, + "libraries": { + "PluginD/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "Microsoft.Extensions.Configuration.Abstractions/2.1.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-VfuZJNa0WUshZ/+8BFZAhwFKiKuu/qOUCFntfdLpHj7vcRnsGHqd3G2Hse78DM+pgozczGM63lGPRLmy+uhUOA==", + "path": "microsoft.extensions.configuration.abstractions/2.1.1", + "hashPath": "microsoft.extensions.configuration.abstractions.2.1.1.nupkg.sha512" + }, + "Microsoft.Extensions.DependencyInjection/2.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-gqQviLfuA31PheEGi+XJoZc1bc9H9RsPa9Gq9XuDct7XGWSR9eVXjK5Sg7CSUPhTFHSuxUFY12wcTYLZ4zM1hg==", + "path": "microsoft.extensions.dependencyinjection/2.1.0", + "hashPath": "microsoft.extensions.dependencyinjection.2.1.0.nupkg.sha512" + }, + "Microsoft.Extensions.DependencyInjection.Abstractions/2.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-8/CtASu80UIoyG+r8FstrmZW5GLtXxzoYpjj3jV0FKZCL5CiFgSH3pAmqut/dC68mu7N1bU6v0UtKKL3gCUQGQ==", + "path": "microsoft.extensions.dependencyinjection.abstractions/2.1.0", + "hashPath": "microsoft.extensions.dependencyinjection.abstractions.2.1.0.nupkg.sha512" + }, + "Microsoft.Extensions.Primitives/2.1.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-scJ1GZNIxMmjpENh0UZ8XCQ6vzr/LzeF9WvEA51Ix2OQGAs9WPgPu8ABVUdvpKPLuor/t05gm6menJK3PwqOXg==", + "path": "microsoft.extensions.primitives/2.1.1", + "hashPath": "microsoft.extensions.primitives.2.1.1.nupkg.sha512" + }, + "Newtonsoft.Json/11.0.2": { + "type": "package", + "serviceable": true, + "sha512": "sha512-IvJe1pj7JHEsP8B8J8DwlMEx8UInrs/x+9oVY+oCD13jpLu4JbJU2WCIsMRn5C4yW9+DgkaO8uiVE5VHKjpmdQ==", + "path": "newtonsoft.json/11.0.2", + "hashPath": "newtonsoft.json.11.0.2.nupkg.sha512" + }, + "System.Memory/4.5.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-sDJYJpGtTgx+23Ayu5euxG5mAXWdkDb4+b0rD0Cab0M1oQS9H0HXGPriKcqpXuiJDTV7fTp/d+fMDJmnr6sNvA==", + "path": "system.memory/4.5.1", + "hashPath": "system.memory.4.5.1.nupkg.sha512" + }, + "System.Runtime.CompilerServices.Unsafe/4.5.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-Zh8t8oqolRaFa9vmOZfdQm/qKejdqz0J9kr7o2Fu0vPeoH3BL1EOXipKWwkWtLT1JPzjByrF19fGuFlNbmPpiw==", + "path": "system.runtime.compilerservices.unsafe/4.5.1", + "hashPath": "system.runtime.compilerservices.unsafe.4.5.1.nupkg.sha512" + }, + "Dictionary.Domain/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "ExternalServiceForPluginD/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "Prise.IntegrationTestsContract/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "Prise.Plugin/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "Prise.PluginBridge/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + } + } +} \ No newline at end of file diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginD/PluginD.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginD/PluginD.dll new file mode 100644 index 0000000..f65de64 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginD/PluginD.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginD/PluginD.pdb b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginD/PluginD.pdb new file mode 100644 index 0000000..d44d268 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginD/PluginD.pdb differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginD/Prise.IntegrationTestsContract.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginD/Prise.IntegrationTestsContract.dll new file mode 100644 index 0000000..8eb98f9 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginD/Prise.IntegrationTestsContract.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginD/Prise.IntegrationTestsContract.pdb b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginD/Prise.IntegrationTestsContract.pdb new file mode 100644 index 0000000..b42bf62 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginD/Prise.IntegrationTestsContract.pdb differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginD/Prise.Plugin.net2.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginD/Prise.Plugin.net2.dll new file mode 100644 index 0000000..10bd95b Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginD/Prise.Plugin.net2.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginD/Prise.Plugin.net2.pdb b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginD/Prise.Plugin.net2.pdb new file mode 100644 index 0000000..64ee468 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginD/Prise.Plugin.net2.pdb differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginD/Prise.PluginBridge.net2.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginD/Prise.PluginBridge.net2.dll new file mode 100644 index 0000000..56d5af1 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginD/Prise.PluginBridge.net2.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginD/Prise.PluginBridge.net2.pdb b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginD/Prise.PluginBridge.net2.pdb new file mode 100644 index 0000000..f0daf65 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginD/Prise.PluginBridge.net2.pdb differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginD/System.Runtime.CompilerServices.Unsafe.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginD/System.Runtime.CompilerServices.Unsafe.dll new file mode 100644 index 0000000..a8df002 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginD/System.Runtime.CompilerServices.Unsafe.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginE/Microsoft.Extensions.DependencyInjection.Abstractions.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginE/Microsoft.Extensions.DependencyInjection.Abstractions.dll new file mode 100644 index 0000000..e557f9d Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginE/Microsoft.Extensions.DependencyInjection.Abstractions.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginE/Microsoft.Extensions.DependencyInjection.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginE/Microsoft.Extensions.DependencyInjection.dll new file mode 100644 index 0000000..fc9b787 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginE/Microsoft.Extensions.DependencyInjection.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginE/Newtonsoft.Json.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginE/Newtonsoft.Json.dll new file mode 100644 index 0000000..e2118f9 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginE/Newtonsoft.Json.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginE/PluginE.deps.json b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginE/PluginE.deps.json new file mode 100644 index 0000000..fe91cd2 --- /dev/null +++ b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginE/PluginE.deps.json @@ -0,0 +1,99 @@ +{ + "runtimeTarget": { + "name": ".NETCoreApp,Version=v2.1", + "signature": "" + }, + "compilationOptions": {}, + "targets": { + ".NETCoreApp,Version=v2.1": { + "PluginE/1.0.0": { + "dependencies": { + "Newtonsoft.Json": "11.0.2", + "Prise.IntegrationTestsContract": "1.0.0", + "Prise.Plugin": "1.0.0" + }, + "runtime": { + "PluginE.dll": {} + } + }, + "Microsoft.Extensions.DependencyInjection/2.1.0": { + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "2.1.0" + }, + "runtime": { + "lib/netcoreapp2.0/Microsoft.Extensions.DependencyInjection.dll": { + "assemblyVersion": "2.1.0.0", + "fileVersion": "2.1.0.18136" + } + } + }, + "Microsoft.Extensions.DependencyInjection.Abstractions/2.1.0": { + "runtime": { + "lib/netstandard2.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll": { + "assemblyVersion": "2.1.0.0", + "fileVersion": "2.1.0.18136" + } + } + }, + "Newtonsoft.Json/11.0.2": { + "runtime": { + "lib/netstandard2.0/Newtonsoft.Json.dll": { + "assemblyVersion": "11.0.0.0", + "fileVersion": "11.0.2.21924" + } + } + }, + "Prise.IntegrationTestsContract/1.0.0": { + "runtime": { + "Prise.IntegrationTestsContract.dll": {} + } + }, + "Prise.Plugin/1.0.0": { + "dependencies": { + "Microsoft.Extensions.DependencyInjection": "2.1.0" + }, + "runtime": { + "Prise.Plugin.net2.dll": {} + } + } + } + }, + "libraries": { + "PluginE/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "Microsoft.Extensions.DependencyInjection/2.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-gqQviLfuA31PheEGi+XJoZc1bc9H9RsPa9Gq9XuDct7XGWSR9eVXjK5Sg7CSUPhTFHSuxUFY12wcTYLZ4zM1hg==", + "path": "microsoft.extensions.dependencyinjection/2.1.0", + "hashPath": "microsoft.extensions.dependencyinjection.2.1.0.nupkg.sha512" + }, + "Microsoft.Extensions.DependencyInjection.Abstractions/2.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-8/CtASu80UIoyG+r8FstrmZW5GLtXxzoYpjj3jV0FKZCL5CiFgSH3pAmqut/dC68mu7N1bU6v0UtKKL3gCUQGQ==", + "path": "microsoft.extensions.dependencyinjection.abstractions/2.1.0", + "hashPath": "microsoft.extensions.dependencyinjection.abstractions.2.1.0.nupkg.sha512" + }, + "Newtonsoft.Json/11.0.2": { + "type": "package", + "serviceable": true, + "sha512": "sha512-IvJe1pj7JHEsP8B8J8DwlMEx8UInrs/x+9oVY+oCD13jpLu4JbJU2WCIsMRn5C4yW9+DgkaO8uiVE5VHKjpmdQ==", + "path": "newtonsoft.json/11.0.2", + "hashPath": "newtonsoft.json.11.0.2.nupkg.sha512" + }, + "Prise.IntegrationTestsContract/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "Prise.Plugin/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + } + } +} \ No newline at end of file diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginE/PluginE.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginE/PluginE.dll new file mode 100644 index 0000000..c33cfa9 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginE/PluginE.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginE/PluginE.pdb b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginE/PluginE.pdb new file mode 100644 index 0000000..38fa699 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginE/PluginE.pdb differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginE/Prise.IntegrationTestsContract.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginE/Prise.IntegrationTestsContract.dll new file mode 100644 index 0000000..8eb98f9 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginE/Prise.IntegrationTestsContract.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginE/Prise.IntegrationTestsContract.pdb b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginE/Prise.IntegrationTestsContract.pdb new file mode 100644 index 0000000..b42bf62 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginE/Prise.IntegrationTestsContract.pdb differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginE/Prise.Plugin.net2.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginE/Prise.Plugin.net2.dll new file mode 100644 index 0000000..10bd95b Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginE/Prise.Plugin.net2.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginE/Prise.Plugin.net2.pdb b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginE/Prise.Plugin.net2.pdb new file mode 100644 index 0000000..64ee468 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginE/Prise.Plugin.net2.pdb differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginF/Microsoft.Bcl.AsyncInterfaces.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginF/Microsoft.Bcl.AsyncInterfaces.dll new file mode 100644 index 0000000..73223c8 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginF/Microsoft.Bcl.AsyncInterfaces.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginF/Microsoft.Extensions.DependencyInjection.Abstractions.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginF/Microsoft.Extensions.DependencyInjection.Abstractions.dll new file mode 100644 index 0000000..e557f9d Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginF/Microsoft.Extensions.DependencyInjection.Abstractions.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginF/Microsoft.Extensions.DependencyInjection.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginF/Microsoft.Extensions.DependencyInjection.dll new file mode 100644 index 0000000..fc9b787 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginF/Microsoft.Extensions.DependencyInjection.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginF/PluginF.deps.json b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginF/PluginF.deps.json new file mode 100644 index 0000000..07e2c3e --- /dev/null +++ b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginF/PluginF.deps.json @@ -0,0 +1,160 @@ +{ + "runtimeTarget": { + "name": ".NETCoreApp,Version=v2.1", + "signature": "" + }, + "compilationOptions": {}, + "targets": { + ".NETCoreApp,Version=v2.1": { + "PluginF/1.0.0": { + "dependencies": { + "Prise.IntegrationTestsContract": "1.0.0", + "Prise.Plugin": "1.0.0", + "System.Text.Json": "4.7.0", + "XmlSerializerLib": "1.0.0" + }, + "runtime": { + "PluginF.dll": {} + } + }, + "Microsoft.Bcl.AsyncInterfaces/1.1.0": { + "runtime": { + "lib/netstandard2.0/Microsoft.Bcl.AsyncInterfaces.dll": { + "assemblyVersion": "1.0.0.0", + "fileVersion": "4.700.19.56404" + } + } + }, + "Microsoft.Extensions.DependencyInjection/2.1.0": { + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "2.1.0" + }, + "runtime": { + "lib/netcoreapp2.0/Microsoft.Extensions.DependencyInjection.dll": { + "assemblyVersion": "2.1.0.0", + "fileVersion": "2.1.0.18136" + } + } + }, + "Microsoft.Extensions.DependencyInjection.Abstractions/2.1.0": { + "runtime": { + "lib/netstandard2.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll": { + "assemblyVersion": "2.1.0.0", + "fileVersion": "2.1.0.18136" + } + } + }, + "System.Runtime.CompilerServices.Unsafe/4.7.0": { + "runtime": { + "lib/netcoreapp2.0/System.Runtime.CompilerServices.Unsafe.dll": { + "assemblyVersion": "4.0.6.0", + "fileVersion": "4.700.19.56404" + } + } + }, + "System.Text.Encodings.Web/4.7.0": { + "runtime": { + "lib/netstandard2.0/System.Text.Encodings.Web.dll": { + "assemblyVersion": "4.0.5.0", + "fileVersion": "4.700.19.56404" + } + } + }, + "System.Text.Json/4.7.0": { + "dependencies": { + "Microsoft.Bcl.AsyncInterfaces": "1.1.0", + "System.Runtime.CompilerServices.Unsafe": "4.7.0", + "System.Text.Encodings.Web": "4.7.0" + }, + "runtime": { + "lib/netstandard2.0/System.Text.Json.dll": { + "assemblyVersion": "4.0.1.0", + "fileVersion": "4.700.19.56404" + } + } + }, + "Prise.IntegrationTestsContract/1.0.0": { + "runtime": { + "Prise.IntegrationTestsContract.dll": {} + } + }, + "Prise.Plugin/1.0.0": { + "dependencies": { + "Microsoft.Extensions.DependencyInjection": "2.1.0" + }, + "runtime": { + "Prise.Plugin.dll": {} + } + }, + "XmlSerializerLib/1.0.0": { + "runtime": { + "XmlSerializerLib.dll": {} + } + } + } + }, + "libraries": { + "PluginF/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "Microsoft.Bcl.AsyncInterfaces/1.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-1Am6l4Vpn3/K32daEqZI+FFr96OlZkgwK2LcT3pZ2zWubR5zTPW3/FkO1Rat9kb7oQOa4rxgl9LJHc5tspCWfg==", + "path": "microsoft.bcl.asyncinterfaces/1.1.0", + "hashPath": "microsoft.bcl.asyncinterfaces.1.1.0.nupkg.sha512" + }, + "Microsoft.Extensions.DependencyInjection/2.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-gqQviLfuA31PheEGi+XJoZc1bc9H9RsPa9Gq9XuDct7XGWSR9eVXjK5Sg7CSUPhTFHSuxUFY12wcTYLZ4zM1hg==", + "path": "microsoft.extensions.dependencyinjection/2.1.0", + "hashPath": "microsoft.extensions.dependencyinjection.2.1.0.nupkg.sha512" + }, + "Microsoft.Extensions.DependencyInjection.Abstractions/2.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-8/CtASu80UIoyG+r8FstrmZW5GLtXxzoYpjj3jV0FKZCL5CiFgSH3pAmqut/dC68mu7N1bU6v0UtKKL3gCUQGQ==", + "path": "microsoft.extensions.dependencyinjection.abstractions/2.1.0", + "hashPath": "microsoft.extensions.dependencyinjection.abstractions.2.1.0.nupkg.sha512" + }, + "System.Runtime.CompilerServices.Unsafe/4.7.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-IpU1lcHz8/09yDr9N+Juc7SCgNUz+RohkCQI+KsWKR67XxpFr8Z6c8t1iENCXZuRuNCc4HBwme/MDHNVCwyAKg==", + "path": "system.runtime.compilerservices.unsafe/4.7.0", + "hashPath": "system.runtime.compilerservices.unsafe.4.7.0.nupkg.sha512" + }, + "System.Text.Encodings.Web/4.7.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-IJanJWPQvya2sbGStt3Fkdy4IaomUBSadAfYWeJDQw0zclMk9ixSvMeei6cSmTTQ6ZkGIIAbhHZVCoLR7GgX7Q==", + "path": "system.text.encodings.web/4.7.0", + "hashPath": "system.text.encodings.web.4.7.0.nupkg.sha512" + }, + "System.Text.Json/4.7.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-IPq/x/d5nAcnD3vIyM3AbPOaTgcqrh0AqPSx7U53UFu3M6k1TH1u/eXc9/h4jm/3mpP1WRUpevlPY4PACd7AWw==", + "path": "system.text.json/4.7.0", + "hashPath": "system.text.json.4.7.0.nupkg.sha512" + }, + "Prise.IntegrationTestsContract/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "Prise.Plugin/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "XmlSerializerLib/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + } + } +} \ No newline at end of file diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginF/PluginF.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginF/PluginF.dll new file mode 100644 index 0000000..7a33142 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginF/PluginF.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginF/PluginF.pdb b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginF/PluginF.pdb new file mode 100644 index 0000000..4c0fc00 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginF/PluginF.pdb differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginF/Prise.IntegrationTestsContract.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginF/Prise.IntegrationTestsContract.dll new file mode 100644 index 0000000..0b8c181 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginF/Prise.IntegrationTestsContract.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginF/Prise.IntegrationTestsContract.pdb b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginF/Prise.IntegrationTestsContract.pdb new file mode 100644 index 0000000..dce1764 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginF/Prise.IntegrationTestsContract.pdb differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginF/Prise.Plugin.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginF/Prise.Plugin.dll new file mode 100644 index 0000000..bd80490 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginF/Prise.Plugin.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginF/Prise.Plugin.pdb b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginF/Prise.Plugin.pdb new file mode 100644 index 0000000..ae9bf94 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginF/Prise.Plugin.pdb differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginF/System.Runtime.CompilerServices.Unsafe.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginF/System.Runtime.CompilerServices.Unsafe.dll new file mode 100644 index 0000000..f4bae66 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginF/System.Runtime.CompilerServices.Unsafe.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginF/System.Text.Encodings.Web.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginF/System.Text.Encodings.Web.dll new file mode 100644 index 0000000..3229bdd Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginF/System.Text.Encodings.Web.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginF/System.Text.Json.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginF/System.Text.Json.dll new file mode 100644 index 0000000..a3dd2eb Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginF/System.Text.Json.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginF/XmlSerializerLib.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginF/XmlSerializerLib.dll new file mode 100644 index 0000000..862f0a6 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginF/XmlSerializerLib.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginF/XmlSerializerLib.pdb b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginF/XmlSerializerLib.pdb new file mode 100644 index 0000000..8f16c2f Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginF/XmlSerializerLib.pdb differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginG.1.0.0.nupkg b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginG.1.0.0.nupkg new file mode 100644 index 0000000..028cedb Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginG.1.0.0.nupkg differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginG/Dictionary.Domain.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginG/Dictionary.Domain.dll new file mode 100644 index 0000000..e7075ea Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginG/Dictionary.Domain.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginG/Dictionary.Domain.pdb b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginG/Dictionary.Domain.pdb new file mode 100644 index 0000000..f337317 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginG/Dictionary.Domain.pdb differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginG/ExternalServiceForPluginD.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginG/ExternalServiceForPluginD.dll new file mode 100644 index 0000000..782bc41 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginG/ExternalServiceForPluginD.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginG/ExternalServiceForPluginD.pdb b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginG/ExternalServiceForPluginD.pdb new file mode 100644 index 0000000..983622a Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginG/ExternalServiceForPluginD.pdb differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginG/Microsoft.Extensions.Configuration.Abstractions.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginG/Microsoft.Extensions.Configuration.Abstractions.dll new file mode 100644 index 0000000..2ce4c75 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginG/Microsoft.Extensions.Configuration.Abstractions.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginG/Microsoft.Extensions.DependencyInjection.Abstractions.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginG/Microsoft.Extensions.DependencyInjection.Abstractions.dll new file mode 100644 index 0000000..e557f9d Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginG/Microsoft.Extensions.DependencyInjection.Abstractions.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginG/Microsoft.Extensions.DependencyInjection.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginG/Microsoft.Extensions.DependencyInjection.dll new file mode 100644 index 0000000..fc9b787 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginG/Microsoft.Extensions.DependencyInjection.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginG/Microsoft.Extensions.Primitives.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginG/Microsoft.Extensions.Primitives.dll new file mode 100644 index 0000000..c634db2 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginG/Microsoft.Extensions.Primitives.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginG/Newtonsoft.Json.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginG/Newtonsoft.Json.dll new file mode 100644 index 0000000..e2118f9 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginG/Newtonsoft.Json.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginG/PluginG.deps.json b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginG/PluginG.deps.json new file mode 100644 index 0000000..a51ac24 --- /dev/null +++ b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginG/PluginG.deps.json @@ -0,0 +1,198 @@ +{ + "runtimeTarget": { + "name": ".NETCoreApp,Version=v2.1", + "signature": "" + }, + "compilationOptions": {}, + "targets": { + ".NETCoreApp,Version=v2.1": { + "PluginG/1.0.0": { + "dependencies": { + "Dictionary.Domain": "1.0.0", + "ExternalServiceForPluginD": "1.0.0", + "Microsoft.Extensions.Configuration.Abstractions": "3.1.0", + "Prise.IntegrationTestsContract": "1.0.0", + "Prise.Plugin": "1.0.0", + "Prise.PluginBridge": "1.0.0" + }, + "runtime": { + "PluginG.dll": {} + } + }, + "Microsoft.Extensions.Configuration.Abstractions/3.1.0": { + "dependencies": { + "Microsoft.Extensions.Primitives": "3.1.0" + }, + "runtime": { + "lib/netstandard2.0/Microsoft.Extensions.Configuration.Abstractions.dll": { + "assemblyVersion": "3.1.0.0", + "fileVersion": "3.100.19.56504" + } + } + }, + "Microsoft.Extensions.DependencyInjection/2.1.0": { + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "2.1.0" + }, + "runtime": { + "lib/netcoreapp2.0/Microsoft.Extensions.DependencyInjection.dll": { + "assemblyVersion": "2.1.0.0", + "fileVersion": "2.1.0.18136" + } + } + }, + "Microsoft.Extensions.DependencyInjection.Abstractions/2.1.0": { + "runtime": { + "lib/netstandard2.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll": { + "assemblyVersion": "2.1.0.0", + "fileVersion": "2.1.0.18136" + } + } + }, + "Microsoft.Extensions.Primitives/3.1.0": { + "dependencies": { + "System.Memory": "4.5.2", + "System.Runtime.CompilerServices.Unsafe": "4.7.0" + }, + "runtime": { + "lib/netstandard2.0/Microsoft.Extensions.Primitives.dll": { + "assemblyVersion": "3.1.0.0", + "fileVersion": "3.100.19.56504" + } + } + }, + "Newtonsoft.Json/11.0.2": { + "runtime": { + "lib/netstandard2.0/Newtonsoft.Json.dll": { + "assemblyVersion": "11.0.0.0", + "fileVersion": "11.0.2.21924" + } + } + }, + "System.Memory/4.5.2": {}, + "System.Runtime.CompilerServices.Unsafe/4.7.0": { + "runtime": { + "lib/netcoreapp2.0/System.Runtime.CompilerServices.Unsafe.dll": { + "assemblyVersion": "4.0.6.0", + "fileVersion": "4.700.19.56404" + } + } + }, + "Dictionary.Domain/1.0.0": { + "dependencies": { + "Newtonsoft.Json": "11.0.2" + }, + "runtime": { + "Dictionary.Domain.dll": {} + } + }, + "ExternalServiceForPluginD/1.0.0": { + "runtime": { + "ExternalServiceForPluginD.dll": {} + } + }, + "Prise.IntegrationTestsContract/1.0.0": { + "runtime": { + "Prise.IntegrationTestsContract.dll": {} + } + }, + "Prise.Plugin/1.0.0": { + "dependencies": { + "Microsoft.Extensions.DependencyInjection": "2.1.0" + }, + "runtime": { + "Prise.Plugin.net2.dll": {} + } + }, + "Prise.PluginBridge/1.0.0": { + "dependencies": { + "Newtonsoft.Json": "11.0.2" + }, + "runtime": { + "Prise.PluginBridge.net2.dll": {} + } + } + } + }, + "libraries": { + "PluginG/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "Microsoft.Extensions.Configuration.Abstractions/3.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-ESz6bVoDQX7sgWdKHF6G9Pq672T8k+19AFb/txDXwdz7MoqaNQj2/in3agm/3qae9V+WvQZH86LLTNVo0it8vQ==", + "path": "microsoft.extensions.configuration.abstractions/3.1.0", + "hashPath": "microsoft.extensions.configuration.abstractions.3.1.0.nupkg.sha512" + }, + "Microsoft.Extensions.DependencyInjection/2.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-gqQviLfuA31PheEGi+XJoZc1bc9H9RsPa9Gq9XuDct7XGWSR9eVXjK5Sg7CSUPhTFHSuxUFY12wcTYLZ4zM1hg==", + "path": "microsoft.extensions.dependencyinjection/2.1.0", + "hashPath": "microsoft.extensions.dependencyinjection.2.1.0.nupkg.sha512" + }, + "Microsoft.Extensions.DependencyInjection.Abstractions/2.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-8/CtASu80UIoyG+r8FstrmZW5GLtXxzoYpjj3jV0FKZCL5CiFgSH3pAmqut/dC68mu7N1bU6v0UtKKL3gCUQGQ==", + "path": "microsoft.extensions.dependencyinjection.abstractions/2.1.0", + "hashPath": "microsoft.extensions.dependencyinjection.abstractions.2.1.0.nupkg.sha512" + }, + "Microsoft.Extensions.Primitives/3.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-LEKAnX7lhUhSoIc2XraCTK3M4IU/LdVUzCe464Sa4+7F4ZJuXHHRzZli2mDbiT4xzAZhgqXbvfnb5+CNDcQFfg==", + "path": "microsoft.extensions.primitives/3.1.0", + "hashPath": "microsoft.extensions.primitives.3.1.0.nupkg.sha512" + }, + "Newtonsoft.Json/11.0.2": { + "type": "package", + "serviceable": true, + "sha512": "sha512-IvJe1pj7JHEsP8B8J8DwlMEx8UInrs/x+9oVY+oCD13jpLu4JbJU2WCIsMRn5C4yW9+DgkaO8uiVE5VHKjpmdQ==", + "path": "newtonsoft.json/11.0.2", + "hashPath": "newtonsoft.json.11.0.2.nupkg.sha512" + }, + "System.Memory/4.5.2": { + "type": "package", + "serviceable": true, + "sha512": "sha512-fvq1GNmUFwbKv+aLVYYdgu/+gc8Nu9oFujOxIjPrsf+meis9JBzTPDL6aP/eeGOz9yPj6rRLUbOjKMpsMEWpNg==", + "path": "system.memory/4.5.2", + "hashPath": "system.memory.4.5.2.nupkg.sha512" + }, + "System.Runtime.CompilerServices.Unsafe/4.7.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-IpU1lcHz8/09yDr9N+Juc7SCgNUz+RohkCQI+KsWKR67XxpFr8Z6c8t1iENCXZuRuNCc4HBwme/MDHNVCwyAKg==", + "path": "system.runtime.compilerservices.unsafe/4.7.0", + "hashPath": "system.runtime.compilerservices.unsafe.4.7.0.nupkg.sha512" + }, + "Dictionary.Domain/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "ExternalServiceForPluginD/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "Prise.IntegrationTestsContract/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "Prise.Plugin/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "Prise.PluginBridge/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + } + } +} \ No newline at end of file diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginG/PluginG.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginG/PluginG.dll new file mode 100644 index 0000000..294bd71 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginG/PluginG.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginG/PluginG.pdb b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginG/PluginG.pdb new file mode 100644 index 0000000..11238a8 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginG/PluginG.pdb differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginG/Prise.IntegrationTestsContract.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginG/Prise.IntegrationTestsContract.dll new file mode 100644 index 0000000..691d877 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginG/Prise.IntegrationTestsContract.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginG/Prise.IntegrationTestsContract.pdb b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginG/Prise.IntegrationTestsContract.pdb new file mode 100644 index 0000000..1ef70ca Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginG/Prise.IntegrationTestsContract.pdb differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginG/Prise.Plugin.net2.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginG/Prise.Plugin.net2.dll new file mode 100644 index 0000000..530ca18 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginG/Prise.Plugin.net2.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginG/Prise.Plugin.net2.pdb b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginG/Prise.Plugin.net2.pdb new file mode 100644 index 0000000..590808a Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginG/Prise.Plugin.net2.pdb differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginG/Prise.PluginBridge.net2.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginG/Prise.PluginBridge.net2.dll new file mode 100644 index 0000000..b9b624e Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginG/Prise.PluginBridge.net2.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginG/Prise.PluginBridge.net2.pdb b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginG/Prise.PluginBridge.net2.pdb new file mode 100644 index 0000000..4be2345 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginG/Prise.PluginBridge.net2.pdb differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginG/System.Runtime.CompilerServices.Unsafe.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginG/System.Runtime.CompilerServices.Unsafe.dll new file mode 100644 index 0000000..f4bae66 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp2.1/PluginG/System.Runtime.CompilerServices.Unsafe.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginD/Dictionary.Domain.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginD/Dictionary.Domain.dll new file mode 100644 index 0000000..e12c845 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginD/Dictionary.Domain.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginD/Dictionary.Domain.pdb b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginD/Dictionary.Domain.pdb new file mode 100644 index 0000000..cd2548b Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginD/Dictionary.Domain.pdb differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginD/ExternalServiceForPluginD.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginD/ExternalServiceForPluginD.dll new file mode 100644 index 0000000..862ad25 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginD/ExternalServiceForPluginD.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginD/ExternalServiceForPluginD.pdb b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginD/ExternalServiceForPluginD.pdb new file mode 100644 index 0000000..86d43a3 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginD/ExternalServiceForPluginD.pdb differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginD/Microsoft.Extensions.Configuration.Abstractions.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginD/Microsoft.Extensions.Configuration.Abstractions.dll new file mode 100644 index 0000000..1423e0d Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginD/Microsoft.Extensions.Configuration.Abstractions.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginD/Microsoft.Extensions.DependencyInjection.Abstractions.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginD/Microsoft.Extensions.DependencyInjection.Abstractions.dll new file mode 100644 index 0000000..d899b25 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginD/Microsoft.Extensions.DependencyInjection.Abstractions.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginD/Microsoft.Extensions.DependencyInjection.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginD/Microsoft.Extensions.DependencyInjection.dll new file mode 100644 index 0000000..e2caf09 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginD/Microsoft.Extensions.DependencyInjection.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginD/Microsoft.Extensions.Primitives.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginD/Microsoft.Extensions.Primitives.dll new file mode 100644 index 0000000..742d2d4 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginD/Microsoft.Extensions.Primitives.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginD/Newtonsoft.Json.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginD/Newtonsoft.Json.dll new file mode 100644 index 0000000..e2118f9 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginD/Newtonsoft.Json.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginD/PluginD.deps.json b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginD/PluginD.deps.json new file mode 100644 index 0000000..89cecc5 --- /dev/null +++ b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginD/PluginD.deps.json @@ -0,0 +1,168 @@ +{ + "runtimeTarget": { + "name": ".NETCoreApp,Version=v3.0", + "signature": "" + }, + "compilationOptions": {}, + "targets": { + ".NETCoreApp,Version=v3.0": { + "PluginD/1.0.0": { + "dependencies": { + "Dictionary.Domain": "1.0.0", + "ExternalServiceForPluginD": "1.0.0", + "Microsoft.Extensions.Configuration.Abstractions": "3.0.0", + "Prise.IntegrationTestsContract": "1.0.0", + "Prise.Plugin": "1.0.0", + "Prise.PluginBridge": "1.0.0" + }, + "runtime": { + "PluginD.dll": {} + } + }, + "Microsoft.Extensions.Configuration.Abstractions/3.0.0": { + "dependencies": { + "Microsoft.Extensions.Primitives": "3.0.0" + }, + "runtime": { + "lib/netcoreapp3.0/Microsoft.Extensions.Configuration.Abstractions.dll": { + "assemblyVersion": "3.0.0.0", + "fileVersion": "3.0.19.46305" + } + } + }, + "Microsoft.Extensions.DependencyInjection/3.0.0": { + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "3.0.0" + }, + "runtime": { + "lib/netcoreapp3.0/Microsoft.Extensions.DependencyInjection.dll": { + "assemblyVersion": "3.0.0.0", + "fileVersion": "3.0.19.46305" + } + } + }, + "Microsoft.Extensions.DependencyInjection.Abstractions/3.0.0": { + "runtime": { + "lib/netstandard2.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll": { + "assemblyVersion": "3.0.0.0", + "fileVersion": "3.0.19.46305" + } + } + }, + "Microsoft.Extensions.Primitives/3.0.0": { + "runtime": { + "lib/netcoreapp3.0/Microsoft.Extensions.Primitives.dll": { + "assemblyVersion": "3.0.0.0", + "fileVersion": "3.0.19.46305" + } + } + }, + "Newtonsoft.Json/11.0.2": { + "runtime": { + "lib/netstandard2.0/Newtonsoft.Json.dll": { + "assemblyVersion": "11.0.0.0", + "fileVersion": "11.0.2.21924" + } + } + }, + "Dictionary.Domain/1.0.0": { + "dependencies": { + "Newtonsoft.Json": "11.0.2" + }, + "runtime": { + "Dictionary.Domain.dll": {} + } + }, + "ExternalServiceForPluginD/1.0.0": { + "runtime": { + "ExternalServiceForPluginD.dll": {} + } + }, + "Prise.IntegrationTestsContract/1.0.0": { + "runtime": { + "Prise.IntegrationTestsContract.dll": {} + } + }, + "Prise.Plugin/1.0.0": { + "dependencies": { + "Microsoft.Extensions.DependencyInjection": "3.0.0" + }, + "runtime": { + "Prise.Plugin.dll": {} + } + }, + "Prise.PluginBridge/1.0.0": { + "runtime": { + "Prise.PluginBridge.dll": {} + } + } + } + }, + "libraries": { + "PluginD/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "Microsoft.Extensions.Configuration.Abstractions/3.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-Lge/PbXC53jI1MF2J92X5EZOeKV8Q/rlB1aV3H9I/ZTDyQGOyBcL03IAvnviWpHKj43BDkNy6kU2KKoh8kAS0g==", + "path": "microsoft.extensions.configuration.abstractions/3.0.0", + "hashPath": "microsoft.extensions.configuration.abstractions.3.0.0.nupkg.sha512" + }, + "Microsoft.Extensions.DependencyInjection/3.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-yDsuNA/BT4j9qrcRs0NUNHQAJfywFWX18ZZ+shxXJL+/nIfz3vhuRTfnYgvFeQlNBlgmgdSjOcs4ajgoS6Q/Ng==", + "path": "microsoft.extensions.dependencyinjection/3.0.0", + "hashPath": "microsoft.extensions.dependencyinjection.3.0.0.nupkg.sha512" + }, + "Microsoft.Extensions.DependencyInjection.Abstractions/3.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-ofQRroDlzJ0xKOtzNuaVt6QKNImFkhkG0lIMpGl7PtXnIf5SuLWBeiQZAP8DNSxDBJJdcsPkiJiMYK2WA5H8dQ==", + "path": "microsoft.extensions.dependencyinjection.abstractions/3.0.0", + "hashPath": "microsoft.extensions.dependencyinjection.abstractions.3.0.0.nupkg.sha512" + }, + "Microsoft.Extensions.Primitives/3.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-6gwewTbmOh+ZVBicVkL1XRp79sx4O7BVY6Yy+7OYZdwn3pyOKe9lOam+3gXJ3TZMjhJZdV0Ub8hxHt2vkrmN5Q==", + "path": "microsoft.extensions.primitives/3.0.0", + "hashPath": "microsoft.extensions.primitives.3.0.0.nupkg.sha512" + }, + "Newtonsoft.Json/11.0.2": { + "type": "package", + "serviceable": true, + "sha512": "sha512-IvJe1pj7JHEsP8B8J8DwlMEx8UInrs/x+9oVY+oCD13jpLu4JbJU2WCIsMRn5C4yW9+DgkaO8uiVE5VHKjpmdQ==", + "path": "newtonsoft.json/11.0.2", + "hashPath": "newtonsoft.json.11.0.2.nupkg.sha512" + }, + "Dictionary.Domain/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "ExternalServiceForPluginD/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "Prise.IntegrationTestsContract/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "Prise.Plugin/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "Prise.PluginBridge/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + } + } +} \ No newline at end of file diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginD/PluginD.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginD/PluginD.dll new file mode 100644 index 0000000..d4add4d Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginD/PluginD.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginD/PluginD.pdb b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginD/PluginD.pdb new file mode 100644 index 0000000..117122c Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginD/PluginD.pdb differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginD/Prise.IntegrationTestsContract.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginD/Prise.IntegrationTestsContract.dll new file mode 100644 index 0000000..8eb98f9 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginD/Prise.IntegrationTestsContract.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginD/Prise.IntegrationTestsContract.pdb b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginD/Prise.IntegrationTestsContract.pdb new file mode 100644 index 0000000..b42bf62 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginD/Prise.IntegrationTestsContract.pdb differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginD/Prise.Plugin.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginD/Prise.Plugin.dll new file mode 100644 index 0000000..12c6767 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginD/Prise.Plugin.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginD/Prise.Plugin.pdb b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginD/Prise.Plugin.pdb new file mode 100644 index 0000000..c153ddc Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginD/Prise.Plugin.pdb differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginD/Prise.PluginBridge.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginD/Prise.PluginBridge.dll new file mode 100644 index 0000000..c9a0d44 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginD/Prise.PluginBridge.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginD/Prise.PluginBridge.pdb b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginD/Prise.PluginBridge.pdb new file mode 100644 index 0000000..34b7f36 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginD/Prise.PluginBridge.pdb differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginE/Microsoft.Extensions.DependencyInjection.Abstractions.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginE/Microsoft.Extensions.DependencyInjection.Abstractions.dll new file mode 100644 index 0000000..d899b25 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginE/Microsoft.Extensions.DependencyInjection.Abstractions.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginE/Microsoft.Extensions.DependencyInjection.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginE/Microsoft.Extensions.DependencyInjection.dll new file mode 100644 index 0000000..e2caf09 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginE/Microsoft.Extensions.DependencyInjection.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginE/Newtonsoft.Json.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginE/Newtonsoft.Json.dll new file mode 100644 index 0000000..e2118f9 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginE/Newtonsoft.Json.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginE/PluginE.deps.json b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginE/PluginE.deps.json new file mode 100644 index 0000000..e5f5aab --- /dev/null +++ b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginE/PluginE.deps.json @@ -0,0 +1,99 @@ +{ + "runtimeTarget": { + "name": ".NETCoreApp,Version=v3.0", + "signature": "" + }, + "compilationOptions": {}, + "targets": { + ".NETCoreApp,Version=v3.0": { + "PluginE/1.0.0": { + "dependencies": { + "Newtonsoft.Json": "11.0.2", + "Prise.IntegrationTestsContract": "1.0.0", + "Prise.Plugin": "1.0.0" + }, + "runtime": { + "PluginE.dll": {} + } + }, + "Microsoft.Extensions.DependencyInjection/3.0.0": { + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "3.0.0" + }, + "runtime": { + "lib/netcoreapp3.0/Microsoft.Extensions.DependencyInjection.dll": { + "assemblyVersion": "3.0.0.0", + "fileVersion": "3.0.19.46305" + } + } + }, + "Microsoft.Extensions.DependencyInjection.Abstractions/3.0.0": { + "runtime": { + "lib/netstandard2.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll": { + "assemblyVersion": "3.0.0.0", + "fileVersion": "3.0.19.46305" + } + } + }, + "Newtonsoft.Json/11.0.2": { + "runtime": { + "lib/netstandard2.0/Newtonsoft.Json.dll": { + "assemblyVersion": "11.0.0.0", + "fileVersion": "11.0.2.21924" + } + } + }, + "Prise.IntegrationTestsContract/1.0.0": { + "runtime": { + "Prise.IntegrationTestsContract.dll": {} + } + }, + "Prise.Plugin/1.0.0": { + "dependencies": { + "Microsoft.Extensions.DependencyInjection": "3.0.0" + }, + "runtime": { + "Prise.Plugin.dll": {} + } + } + } + }, + "libraries": { + "PluginE/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "Microsoft.Extensions.DependencyInjection/3.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-yDsuNA/BT4j9qrcRs0NUNHQAJfywFWX18ZZ+shxXJL+/nIfz3vhuRTfnYgvFeQlNBlgmgdSjOcs4ajgoS6Q/Ng==", + "path": "microsoft.extensions.dependencyinjection/3.0.0", + "hashPath": "microsoft.extensions.dependencyinjection.3.0.0.nupkg.sha512" + }, + "Microsoft.Extensions.DependencyInjection.Abstractions/3.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-ofQRroDlzJ0xKOtzNuaVt6QKNImFkhkG0lIMpGl7PtXnIf5SuLWBeiQZAP8DNSxDBJJdcsPkiJiMYK2WA5H8dQ==", + "path": "microsoft.extensions.dependencyinjection.abstractions/3.0.0", + "hashPath": "microsoft.extensions.dependencyinjection.abstractions.3.0.0.nupkg.sha512" + }, + "Newtonsoft.Json/11.0.2": { + "type": "package", + "serviceable": true, + "sha512": "sha512-IvJe1pj7JHEsP8B8J8DwlMEx8UInrs/x+9oVY+oCD13jpLu4JbJU2WCIsMRn5C4yW9+DgkaO8uiVE5VHKjpmdQ==", + "path": "newtonsoft.json/11.0.2", + "hashPath": "newtonsoft.json.11.0.2.nupkg.sha512" + }, + "Prise.IntegrationTestsContract/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "Prise.Plugin/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + } + } +} \ No newline at end of file diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginE/PluginE.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginE/PluginE.dll new file mode 100644 index 0000000..7926de9 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginE/PluginE.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginE/PluginE.pdb b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginE/PluginE.pdb new file mode 100644 index 0000000..3134654 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginE/PluginE.pdb differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginE/Prise.IntegrationTestsContract.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginE/Prise.IntegrationTestsContract.dll new file mode 100644 index 0000000..8eb98f9 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginE/Prise.IntegrationTestsContract.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginE/Prise.IntegrationTestsContract.pdb b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginE/Prise.IntegrationTestsContract.pdb new file mode 100644 index 0000000..b42bf62 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginE/Prise.IntegrationTestsContract.pdb differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginE/Prise.Plugin.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginE/Prise.Plugin.dll new file mode 100644 index 0000000..12c6767 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginE/Prise.Plugin.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginE/Prise.Plugin.pdb b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginE/Prise.Plugin.pdb new file mode 100644 index 0000000..c153ddc Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginE/Prise.Plugin.pdb differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginF/Microsoft.Extensions.DependencyInjection.Abstractions.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginF/Microsoft.Extensions.DependencyInjection.Abstractions.dll new file mode 100644 index 0000000..e557f9d Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginF/Microsoft.Extensions.DependencyInjection.Abstractions.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginF/Microsoft.Extensions.DependencyInjection.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginF/Microsoft.Extensions.DependencyInjection.dll new file mode 100644 index 0000000..fc9b787 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginF/Microsoft.Extensions.DependencyInjection.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginF/PluginF.deps.json b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginF/PluginF.deps.json new file mode 100644 index 0000000..71b3efd --- /dev/null +++ b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginF/PluginF.deps.json @@ -0,0 +1,94 @@ +{ + "runtimeTarget": { + "name": ".NETCoreApp,Version=v3.0", + "signature": "" + }, + "compilationOptions": {}, + "targets": { + ".NETCoreApp,Version=v3.0": { + "PluginF/1.0.0": { + "dependencies": { + "Prise.IntegrationTestsContract": "1.0.0", + "Prise.Plugin": "1.0.0", + "XmlSerializerLib": "1.0.0" + }, + "runtime": { + "PluginF.dll": {} + } + }, + "Microsoft.Extensions.DependencyInjection/2.1.0": { + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "2.1.0" + }, + "runtime": { + "lib/netcoreapp2.0/Microsoft.Extensions.DependencyInjection.dll": { + "assemblyVersion": "2.1.0.0", + "fileVersion": "2.1.0.18136" + } + } + }, + "Microsoft.Extensions.DependencyInjection.Abstractions/2.1.0": { + "runtime": { + "lib/netstandard2.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll": { + "assemblyVersion": "2.1.0.0", + "fileVersion": "2.1.0.18136" + } + } + }, + "Prise.IntegrationTestsContract/1.0.0": { + "runtime": { + "Prise.IntegrationTestsContract.dll": {} + } + }, + "Prise.Plugin/1.0.0": { + "dependencies": { + "Microsoft.Extensions.DependencyInjection": "2.1.0" + }, + "runtime": { + "Prise.Plugin.dll": {} + } + }, + "XmlSerializerLib/1.0.0": { + "runtime": { + "XmlSerializerLib.dll": {} + } + } + } + }, + "libraries": { + "PluginF/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "Microsoft.Extensions.DependencyInjection/2.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-gqQviLfuA31PheEGi+XJoZc1bc9H9RsPa9Gq9XuDct7XGWSR9eVXjK5Sg7CSUPhTFHSuxUFY12wcTYLZ4zM1hg==", + "path": "microsoft.extensions.dependencyinjection/2.1.0", + "hashPath": "microsoft.extensions.dependencyinjection.2.1.0.nupkg.sha512" + }, + "Microsoft.Extensions.DependencyInjection.Abstractions/2.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-8/CtASu80UIoyG+r8FstrmZW5GLtXxzoYpjj3jV0FKZCL5CiFgSH3pAmqut/dC68mu7N1bU6v0UtKKL3gCUQGQ==", + "path": "microsoft.extensions.dependencyinjection.abstractions/2.1.0", + "hashPath": "microsoft.extensions.dependencyinjection.abstractions.2.1.0.nupkg.sha512" + }, + "Prise.IntegrationTestsContract/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "Prise.Plugin/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "XmlSerializerLib/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + } + } +} \ No newline at end of file diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginF/PluginF.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginF/PluginF.dll new file mode 100644 index 0000000..4a72b2e Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginF/PluginF.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginF/PluginF.pdb b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginF/PluginF.pdb new file mode 100644 index 0000000..aa1e47b Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginF/PluginF.pdb differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginF/Prise.IntegrationTestsContract.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginF/Prise.IntegrationTestsContract.dll new file mode 100644 index 0000000..0b8c181 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginF/Prise.IntegrationTestsContract.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginF/Prise.IntegrationTestsContract.pdb b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginF/Prise.IntegrationTestsContract.pdb new file mode 100644 index 0000000..dce1764 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginF/Prise.IntegrationTestsContract.pdb differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginF/Prise.Plugin.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginF/Prise.Plugin.dll new file mode 100644 index 0000000..bd80490 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginF/Prise.Plugin.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginF/Prise.Plugin.pdb b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginF/Prise.Plugin.pdb new file mode 100644 index 0000000..ae9bf94 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginF/Prise.Plugin.pdb differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginF/XmlSerializerLib.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginF/XmlSerializerLib.dll new file mode 100644 index 0000000..862f0a6 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginF/XmlSerializerLib.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginF/XmlSerializerLib.pdb b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginF/XmlSerializerLib.pdb new file mode 100644 index 0000000..8f16c2f Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginF/XmlSerializerLib.pdb differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginG.1.0.0.nupkg b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginG.1.0.0.nupkg new file mode 100644 index 0000000..8e13b6d Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginG.1.0.0.nupkg differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginG/Dictionary.Domain.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginG/Dictionary.Domain.dll new file mode 100644 index 0000000..e7075ea Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginG/Dictionary.Domain.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginG/Dictionary.Domain.pdb b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginG/Dictionary.Domain.pdb new file mode 100644 index 0000000..f337317 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginG/Dictionary.Domain.pdb differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginG/ExternalServiceForPluginD.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginG/ExternalServiceForPluginD.dll new file mode 100644 index 0000000..782bc41 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginG/ExternalServiceForPluginD.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginG/ExternalServiceForPluginD.pdb b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginG/ExternalServiceForPluginD.pdb new file mode 100644 index 0000000..983622a Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginG/ExternalServiceForPluginD.pdb differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginG/Microsoft.Extensions.Configuration.Abstractions.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginG/Microsoft.Extensions.Configuration.Abstractions.dll new file mode 100644 index 0000000..1423e0d Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginG/Microsoft.Extensions.Configuration.Abstractions.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginG/Microsoft.Extensions.DependencyInjection.Abstractions.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginG/Microsoft.Extensions.DependencyInjection.Abstractions.dll new file mode 100644 index 0000000..d899b25 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginG/Microsoft.Extensions.DependencyInjection.Abstractions.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginG/Microsoft.Extensions.DependencyInjection.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginG/Microsoft.Extensions.DependencyInjection.dll new file mode 100644 index 0000000..e2caf09 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginG/Microsoft.Extensions.DependencyInjection.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginG/Microsoft.Extensions.Primitives.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginG/Microsoft.Extensions.Primitives.dll new file mode 100644 index 0000000..742d2d4 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginG/Microsoft.Extensions.Primitives.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginG/Newtonsoft.Json.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginG/Newtonsoft.Json.dll new file mode 100644 index 0000000..e2118f9 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginG/Newtonsoft.Json.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginG/PluginG.deps.json b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginG/PluginG.deps.json new file mode 100644 index 0000000..8aba2e7 --- /dev/null +++ b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginG/PluginG.deps.json @@ -0,0 +1,168 @@ +{ + "runtimeTarget": { + "name": ".NETCoreApp,Version=v3.0", + "signature": "" + }, + "compilationOptions": {}, + "targets": { + ".NETCoreApp,Version=v3.0": { + "PluginG/1.0.0": { + "dependencies": { + "Dictionary.Domain": "1.0.0", + "ExternalServiceForPluginD": "1.0.0", + "Microsoft.Extensions.Configuration.Abstractions": "3.0.0", + "Prise.IntegrationTestsContract": "1.0.0", + "Prise.Plugin": "1.0.0", + "Prise.PluginBridge": "1.0.0" + }, + "runtime": { + "PluginG.dll": {} + } + }, + "Microsoft.Extensions.Configuration.Abstractions/3.0.0": { + "dependencies": { + "Microsoft.Extensions.Primitives": "3.0.0" + }, + "runtime": { + "lib/netcoreapp3.0/Microsoft.Extensions.Configuration.Abstractions.dll": { + "assemblyVersion": "3.0.0.0", + "fileVersion": "3.0.19.46305" + } + } + }, + "Microsoft.Extensions.DependencyInjection/3.0.0": { + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "3.0.0" + }, + "runtime": { + "lib/netcoreapp3.0/Microsoft.Extensions.DependencyInjection.dll": { + "assemblyVersion": "3.0.0.0", + "fileVersion": "3.0.19.46305" + } + } + }, + "Microsoft.Extensions.DependencyInjection.Abstractions/3.0.0": { + "runtime": { + "lib/netstandard2.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll": { + "assemblyVersion": "3.0.0.0", + "fileVersion": "3.0.19.46305" + } + } + }, + "Microsoft.Extensions.Primitives/3.0.0": { + "runtime": { + "lib/netcoreapp3.0/Microsoft.Extensions.Primitives.dll": { + "assemblyVersion": "3.0.0.0", + "fileVersion": "3.0.19.46305" + } + } + }, + "Newtonsoft.Json/11.0.2": { + "runtime": { + "lib/netstandard2.0/Newtonsoft.Json.dll": { + "assemblyVersion": "11.0.0.0", + "fileVersion": "11.0.2.21924" + } + } + }, + "Dictionary.Domain/1.0.0": { + "dependencies": { + "Newtonsoft.Json": "11.0.2" + }, + "runtime": { + "Dictionary.Domain.dll": {} + } + }, + "ExternalServiceForPluginD/1.0.0": { + "runtime": { + "ExternalServiceForPluginD.dll": {} + } + }, + "Prise.IntegrationTestsContract/1.0.0": { + "runtime": { + "Prise.IntegrationTestsContract.dll": {} + } + }, + "Prise.Plugin/1.0.0": { + "dependencies": { + "Microsoft.Extensions.DependencyInjection": "3.0.0" + }, + "runtime": { + "Prise.Plugin.dll": {} + } + }, + "Prise.PluginBridge/1.0.0": { + "runtime": { + "Prise.PluginBridge.net3.dll": {} + } + } + } + }, + "libraries": { + "PluginG/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "Microsoft.Extensions.Configuration.Abstractions/3.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-Lge/PbXC53jI1MF2J92X5EZOeKV8Q/rlB1aV3H9I/ZTDyQGOyBcL03IAvnviWpHKj43BDkNy6kU2KKoh8kAS0g==", + "path": "microsoft.extensions.configuration.abstractions/3.0.0", + "hashPath": "microsoft.extensions.configuration.abstractions.3.0.0.nupkg.sha512" + }, + "Microsoft.Extensions.DependencyInjection/3.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-yDsuNA/BT4j9qrcRs0NUNHQAJfywFWX18ZZ+shxXJL+/nIfz3vhuRTfnYgvFeQlNBlgmgdSjOcs4ajgoS6Q/Ng==", + "path": "microsoft.extensions.dependencyinjection/3.0.0", + "hashPath": "microsoft.extensions.dependencyinjection.3.0.0.nupkg.sha512" + }, + "Microsoft.Extensions.DependencyInjection.Abstractions/3.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-ofQRroDlzJ0xKOtzNuaVt6QKNImFkhkG0lIMpGl7PtXnIf5SuLWBeiQZAP8DNSxDBJJdcsPkiJiMYK2WA5H8dQ==", + "path": "microsoft.extensions.dependencyinjection.abstractions/3.0.0", + "hashPath": "microsoft.extensions.dependencyinjection.abstractions.3.0.0.nupkg.sha512" + }, + "Microsoft.Extensions.Primitives/3.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-6gwewTbmOh+ZVBicVkL1XRp79sx4O7BVY6Yy+7OYZdwn3pyOKe9lOam+3gXJ3TZMjhJZdV0Ub8hxHt2vkrmN5Q==", + "path": "microsoft.extensions.primitives/3.0.0", + "hashPath": "microsoft.extensions.primitives.3.0.0.nupkg.sha512" + }, + "Newtonsoft.Json/11.0.2": { + "type": "package", + "serviceable": true, + "sha512": "sha512-IvJe1pj7JHEsP8B8J8DwlMEx8UInrs/x+9oVY+oCD13jpLu4JbJU2WCIsMRn5C4yW9+DgkaO8uiVE5VHKjpmdQ==", + "path": "newtonsoft.json/11.0.2", + "hashPath": "newtonsoft.json.11.0.2.nupkg.sha512" + }, + "Dictionary.Domain/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "ExternalServiceForPluginD/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "Prise.IntegrationTestsContract/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "Prise.Plugin/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "Prise.PluginBridge/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + } + } +} \ No newline at end of file diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginG/PluginG.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginG/PluginG.dll new file mode 100644 index 0000000..54cba3b Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginG/PluginG.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginG/PluginG.pdb b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginG/PluginG.pdb new file mode 100644 index 0000000..1a06ec5 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginG/PluginG.pdb differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginG/Prise.IntegrationTestsContract.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginG/Prise.IntegrationTestsContract.dll new file mode 100644 index 0000000..691d877 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginG/Prise.IntegrationTestsContract.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginG/Prise.IntegrationTestsContract.pdb b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginG/Prise.IntegrationTestsContract.pdb new file mode 100644 index 0000000..1ef70ca Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginG/Prise.IntegrationTestsContract.pdb differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginG/Prise.Plugin.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginG/Prise.Plugin.dll new file mode 100644 index 0000000..6730b94 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginG/Prise.Plugin.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginG/Prise.Plugin.pdb b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginG/Prise.Plugin.pdb new file mode 100644 index 0000000..2569010 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginG/Prise.Plugin.pdb differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginG/Prise.PluginBridge.net3.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginG/Prise.PluginBridge.net3.dll new file mode 100644 index 0000000..e1ca16c Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginG/Prise.PluginBridge.net3.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginG/Prise.PluginBridge.net3.pdb b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginG/Prise.PluginBridge.net3.pdb new file mode 100644 index 0000000..a2f4b8f Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.0/PluginG/Prise.PluginBridge.net3.pdb differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginD/Dictionary.Domain.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginD/Dictionary.Domain.dll new file mode 100644 index 0000000..e7075ea Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginD/Dictionary.Domain.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginD/Dictionary.Domain.pdb b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginD/Dictionary.Domain.pdb new file mode 100644 index 0000000..f337317 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginD/Dictionary.Domain.pdb differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginD/ExternalServiceForPluginD.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginD/ExternalServiceForPluginD.dll new file mode 100644 index 0000000..782bc41 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginD/ExternalServiceForPluginD.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginD/ExternalServiceForPluginD.pdb b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginD/ExternalServiceForPluginD.pdb new file mode 100644 index 0000000..983622a Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginD/ExternalServiceForPluginD.pdb differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginD/Microsoft.Extensions.Configuration.Abstractions.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginD/Microsoft.Extensions.Configuration.Abstractions.dll new file mode 100644 index 0000000..52befe9 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginD/Microsoft.Extensions.Configuration.Abstractions.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginD/Microsoft.Extensions.DependencyInjection.Abstractions.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginD/Microsoft.Extensions.DependencyInjection.Abstractions.dll new file mode 100644 index 0000000..d899b25 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginD/Microsoft.Extensions.DependencyInjection.Abstractions.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginD/Microsoft.Extensions.DependencyInjection.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginD/Microsoft.Extensions.DependencyInjection.dll new file mode 100644 index 0000000..e2caf09 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginD/Microsoft.Extensions.DependencyInjection.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginD/Microsoft.Extensions.Primitives.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginD/Microsoft.Extensions.Primitives.dll new file mode 100644 index 0000000..d12ec5b Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginD/Microsoft.Extensions.Primitives.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginD/Newtonsoft.Json.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginD/Newtonsoft.Json.dll new file mode 100644 index 0000000..e2118f9 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginD/Newtonsoft.Json.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginD/PluginD.deps.json b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginD/PluginD.deps.json new file mode 100644 index 0000000..865ad10 --- /dev/null +++ b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginD/PluginD.deps.json @@ -0,0 +1,168 @@ +{ + "runtimeTarget": { + "name": ".NETCoreApp,Version=v3.1", + "signature": "" + }, + "compilationOptions": {}, + "targets": { + ".NETCoreApp,Version=v3.1": { + "PluginD/1.0.0": { + "dependencies": { + "Dictionary.Domain": "1.0.0", + "ExternalServiceForPluginD": "1.0.0", + "Microsoft.Extensions.Configuration.Abstractions": "3.1.0", + "Prise.IntegrationTestsContract": "1.0.0", + "Prise.Plugin": "1.0.0", + "Prise.PluginBridge": "1.0.0" + }, + "runtime": { + "PluginD.dll": {} + } + }, + "Microsoft.Extensions.Configuration.Abstractions/3.1.0": { + "dependencies": { + "Microsoft.Extensions.Primitives": "3.1.0" + }, + "runtime": { + "lib/netcoreapp3.1/Microsoft.Extensions.Configuration.Abstractions.dll": { + "assemblyVersion": "3.1.0.0", + "fileVersion": "3.100.19.56504" + } + } + }, + "Microsoft.Extensions.DependencyInjection/3.0.0": { + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "3.0.0" + }, + "runtime": { + "lib/netcoreapp3.0/Microsoft.Extensions.DependencyInjection.dll": { + "assemblyVersion": "3.0.0.0", + "fileVersion": "3.0.19.46305" + } + } + }, + "Microsoft.Extensions.DependencyInjection.Abstractions/3.0.0": { + "runtime": { + "lib/netstandard2.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll": { + "assemblyVersion": "3.0.0.0", + "fileVersion": "3.0.19.46305" + } + } + }, + "Microsoft.Extensions.Primitives/3.1.0": { + "runtime": { + "lib/netcoreapp3.1/Microsoft.Extensions.Primitives.dll": { + "assemblyVersion": "3.1.0.0", + "fileVersion": "3.100.19.56504" + } + } + }, + "Newtonsoft.Json/11.0.2": { + "runtime": { + "lib/netstandard2.0/Newtonsoft.Json.dll": { + "assemblyVersion": "11.0.0.0", + "fileVersion": "11.0.2.21924" + } + } + }, + "Dictionary.Domain/1.0.0": { + "dependencies": { + "Newtonsoft.Json": "11.0.2" + }, + "runtime": { + "Dictionary.Domain.dll": {} + } + }, + "ExternalServiceForPluginD/1.0.0": { + "runtime": { + "ExternalServiceForPluginD.dll": {} + } + }, + "Prise.IntegrationTestsContract/1.0.0": { + "runtime": { + "Prise.IntegrationTestsContract.dll": {} + } + }, + "Prise.Plugin/1.0.0": { + "dependencies": { + "Microsoft.Extensions.DependencyInjection": "3.0.0" + }, + "runtime": { + "Prise.Plugin.dll": {} + } + }, + "Prise.PluginBridge/1.0.0": { + "runtime": { + "Prise.PluginBridge.dll": {} + } + } + } + }, + "libraries": { + "PluginD/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "Microsoft.Extensions.Configuration.Abstractions/3.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-ESz6bVoDQX7sgWdKHF6G9Pq672T8k+19AFb/txDXwdz7MoqaNQj2/in3agm/3qae9V+WvQZH86LLTNVo0it8vQ==", + "path": "microsoft.extensions.configuration.abstractions/3.1.0", + "hashPath": "microsoft.extensions.configuration.abstractions.3.1.0.nupkg.sha512" + }, + "Microsoft.Extensions.DependencyInjection/3.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-yDsuNA/BT4j9qrcRs0NUNHQAJfywFWX18ZZ+shxXJL+/nIfz3vhuRTfnYgvFeQlNBlgmgdSjOcs4ajgoS6Q/Ng==", + "path": "microsoft.extensions.dependencyinjection/3.0.0", + "hashPath": "microsoft.extensions.dependencyinjection.3.0.0.nupkg.sha512" + }, + "Microsoft.Extensions.DependencyInjection.Abstractions/3.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-ofQRroDlzJ0xKOtzNuaVt6QKNImFkhkG0lIMpGl7PtXnIf5SuLWBeiQZAP8DNSxDBJJdcsPkiJiMYK2WA5H8dQ==", + "path": "microsoft.extensions.dependencyinjection.abstractions/3.0.0", + "hashPath": "microsoft.extensions.dependencyinjection.abstractions.3.0.0.nupkg.sha512" + }, + "Microsoft.Extensions.Primitives/3.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-LEKAnX7lhUhSoIc2XraCTK3M4IU/LdVUzCe464Sa4+7F4ZJuXHHRzZli2mDbiT4xzAZhgqXbvfnb5+CNDcQFfg==", + "path": "microsoft.extensions.primitives/3.1.0", + "hashPath": "microsoft.extensions.primitives.3.1.0.nupkg.sha512" + }, + "Newtonsoft.Json/11.0.2": { + "type": "package", + "serviceable": true, + "sha512": "sha512-IvJe1pj7JHEsP8B8J8DwlMEx8UInrs/x+9oVY+oCD13jpLu4JbJU2WCIsMRn5C4yW9+DgkaO8uiVE5VHKjpmdQ==", + "path": "newtonsoft.json/11.0.2", + "hashPath": "newtonsoft.json.11.0.2.nupkg.sha512" + }, + "Dictionary.Domain/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "ExternalServiceForPluginD/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "Prise.IntegrationTestsContract/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "Prise.Plugin/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "Prise.PluginBridge/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + } + } +} \ No newline at end of file diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginD/PluginD.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginD/PluginD.dll new file mode 100644 index 0000000..005a50c Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginD/PluginD.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginD/PluginD.pdb b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginD/PluginD.pdb new file mode 100644 index 0000000..21b4a69 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginD/PluginD.pdb differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginD/Prise.IntegrationTestsContract.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginD/Prise.IntegrationTestsContract.dll new file mode 100644 index 0000000..5cdfe44 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginD/Prise.IntegrationTestsContract.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginD/Prise.IntegrationTestsContract.pdb b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginD/Prise.IntegrationTestsContract.pdb new file mode 100644 index 0000000..261bf1d Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginD/Prise.IntegrationTestsContract.pdb differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginD/Prise.Plugin.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginD/Prise.Plugin.dll new file mode 100644 index 0000000..30afb86 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginD/Prise.Plugin.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginD/Prise.Plugin.pdb b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginD/Prise.Plugin.pdb new file mode 100644 index 0000000..7c30993 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginD/Prise.Plugin.pdb differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginD/Prise.PluginBridge.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginD/Prise.PluginBridge.dll new file mode 100644 index 0000000..a8a092d Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginD/Prise.PluginBridge.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginD/Prise.PluginBridge.pdb b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginD/Prise.PluginBridge.pdb new file mode 100644 index 0000000..b4701c3 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginD/Prise.PluginBridge.pdb differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginE/Microsoft.Extensions.DependencyInjection.Abstractions.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginE/Microsoft.Extensions.DependencyInjection.Abstractions.dll new file mode 100644 index 0000000..d899b25 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginE/Microsoft.Extensions.DependencyInjection.Abstractions.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginE/Microsoft.Extensions.DependencyInjection.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginE/Microsoft.Extensions.DependencyInjection.dll new file mode 100644 index 0000000..e2caf09 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginE/Microsoft.Extensions.DependencyInjection.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginE/Newtonsoft.Json.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginE/Newtonsoft.Json.dll new file mode 100644 index 0000000..e2118f9 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginE/Newtonsoft.Json.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginE/PluginE.deps.json b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginE/PluginE.deps.json new file mode 100644 index 0000000..f52e66c --- /dev/null +++ b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginE/PluginE.deps.json @@ -0,0 +1,99 @@ +{ + "runtimeTarget": { + "name": ".NETCoreApp,Version=v3.1", + "signature": "" + }, + "compilationOptions": {}, + "targets": { + ".NETCoreApp,Version=v3.1": { + "PluginE/1.0.0": { + "dependencies": { + "Newtonsoft.Json": "11.0.2", + "Prise.IntegrationTestsContract": "1.0.0", + "Prise.Plugin": "1.0.0" + }, + "runtime": { + "PluginE.dll": {} + } + }, + "Microsoft.Extensions.DependencyInjection/3.0.0": { + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "3.0.0" + }, + "runtime": { + "lib/netcoreapp3.0/Microsoft.Extensions.DependencyInjection.dll": { + "assemblyVersion": "3.0.0.0", + "fileVersion": "3.0.19.46305" + } + } + }, + "Microsoft.Extensions.DependencyInjection.Abstractions/3.0.0": { + "runtime": { + "lib/netstandard2.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll": { + "assemblyVersion": "3.0.0.0", + "fileVersion": "3.0.19.46305" + } + } + }, + "Newtonsoft.Json/11.0.2": { + "runtime": { + "lib/netstandard2.0/Newtonsoft.Json.dll": { + "assemblyVersion": "11.0.0.0", + "fileVersion": "11.0.2.21924" + } + } + }, + "Prise.IntegrationTestsContract/1.0.0": { + "runtime": { + "Prise.IntegrationTestsContract.dll": {} + } + }, + "Prise.Plugin/1.0.0": { + "dependencies": { + "Microsoft.Extensions.DependencyInjection": "3.0.0" + }, + "runtime": { + "Prise.Plugin.dll": {} + } + } + } + }, + "libraries": { + "PluginE/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "Microsoft.Extensions.DependencyInjection/3.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-yDsuNA/BT4j9qrcRs0NUNHQAJfywFWX18ZZ+shxXJL+/nIfz3vhuRTfnYgvFeQlNBlgmgdSjOcs4ajgoS6Q/Ng==", + "path": "microsoft.extensions.dependencyinjection/3.0.0", + "hashPath": "microsoft.extensions.dependencyinjection.3.0.0.nupkg.sha512" + }, + "Microsoft.Extensions.DependencyInjection.Abstractions/3.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-ofQRroDlzJ0xKOtzNuaVt6QKNImFkhkG0lIMpGl7PtXnIf5SuLWBeiQZAP8DNSxDBJJdcsPkiJiMYK2WA5H8dQ==", + "path": "microsoft.extensions.dependencyinjection.abstractions/3.0.0", + "hashPath": "microsoft.extensions.dependencyinjection.abstractions.3.0.0.nupkg.sha512" + }, + "Newtonsoft.Json/11.0.2": { + "type": "package", + "serviceable": true, + "sha512": "sha512-IvJe1pj7JHEsP8B8J8DwlMEx8UInrs/x+9oVY+oCD13jpLu4JbJU2WCIsMRn5C4yW9+DgkaO8uiVE5VHKjpmdQ==", + "path": "newtonsoft.json/11.0.2", + "hashPath": "newtonsoft.json.11.0.2.nupkg.sha512" + }, + "Prise.IntegrationTestsContract/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "Prise.Plugin/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + } + } +} \ No newline at end of file diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginE/PluginE.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginE/PluginE.dll new file mode 100644 index 0000000..17f5192 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginE/PluginE.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginE/PluginE.pdb b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginE/PluginE.pdb new file mode 100644 index 0000000..02c2b95 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginE/PluginE.pdb differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginE/Prise.IntegrationTestsContract.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginE/Prise.IntegrationTestsContract.dll new file mode 100644 index 0000000..5cdfe44 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginE/Prise.IntegrationTestsContract.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginE/Prise.IntegrationTestsContract.pdb b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginE/Prise.IntegrationTestsContract.pdb new file mode 100644 index 0000000..261bf1d Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginE/Prise.IntegrationTestsContract.pdb differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginE/Prise.Plugin.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginE/Prise.Plugin.dll new file mode 100644 index 0000000..30afb86 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginE/Prise.Plugin.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginE/Prise.Plugin.pdb b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginE/Prise.Plugin.pdb new file mode 100644 index 0000000..7c30993 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginE/Prise.Plugin.pdb differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginF/Microsoft.Extensions.DependencyInjection.Abstractions.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginF/Microsoft.Extensions.DependencyInjection.Abstractions.dll new file mode 100644 index 0000000..e557f9d Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginF/Microsoft.Extensions.DependencyInjection.Abstractions.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginF/Microsoft.Extensions.DependencyInjection.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginF/Microsoft.Extensions.DependencyInjection.dll new file mode 100644 index 0000000..fc9b787 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginF/Microsoft.Extensions.DependencyInjection.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginF/PluginF.deps.json b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginF/PluginF.deps.json new file mode 100644 index 0000000..5f341b4 --- /dev/null +++ b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginF/PluginF.deps.json @@ -0,0 +1,103 @@ +{ + "runtimeTarget": { + "name": ".NETCoreApp,Version=v3.1", + "signature": "" + }, + "compilationOptions": {}, + "targets": { + ".NETCoreApp,Version=v3.1": { + "PluginF/1.0.0": { + "dependencies": { + "Prise.IntegrationTestsContract": "1.0.0", + "Prise.Plugin": "1.0.0", + "System.Text.Json": "4.7.0", + "XmlSerializerLib": "1.0.0" + }, + "runtime": { + "PluginF.dll": {} + } + }, + "Microsoft.Extensions.DependencyInjection/2.1.0": { + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "2.1.0" + }, + "runtime": { + "lib/netcoreapp2.0/Microsoft.Extensions.DependencyInjection.dll": { + "assemblyVersion": "2.1.0.0", + "fileVersion": "2.1.0.18136" + } + } + }, + "Microsoft.Extensions.DependencyInjection.Abstractions/2.1.0": { + "runtime": { + "lib/netstandard2.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll": { + "assemblyVersion": "2.1.0.0", + "fileVersion": "2.1.0.18136" + } + } + }, + "System.Text.Json/4.7.0": {}, + "Prise.IntegrationTestsContract/1.0.0": { + "runtime": { + "Prise.IntegrationTestsContract.dll": {} + } + }, + "Prise.Plugin/1.0.0": { + "dependencies": { + "Microsoft.Extensions.DependencyInjection": "2.1.0" + }, + "runtime": { + "Prise.Plugin.dll": {} + } + }, + "XmlSerializerLib/1.0.0": { + "runtime": { + "XmlSerializerLib.dll": {} + } + } + } + }, + "libraries": { + "PluginF/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "Microsoft.Extensions.DependencyInjection/2.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-gqQviLfuA31PheEGi+XJoZc1bc9H9RsPa9Gq9XuDct7XGWSR9eVXjK5Sg7CSUPhTFHSuxUFY12wcTYLZ4zM1hg==", + "path": "microsoft.extensions.dependencyinjection/2.1.0", + "hashPath": "microsoft.extensions.dependencyinjection.2.1.0.nupkg.sha512" + }, + "Microsoft.Extensions.DependencyInjection.Abstractions/2.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-8/CtASu80UIoyG+r8FstrmZW5GLtXxzoYpjj3jV0FKZCL5CiFgSH3pAmqut/dC68mu7N1bU6v0UtKKL3gCUQGQ==", + "path": "microsoft.extensions.dependencyinjection.abstractions/2.1.0", + "hashPath": "microsoft.extensions.dependencyinjection.abstractions.2.1.0.nupkg.sha512" + }, + "System.Text.Json/4.7.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-IPq/x/d5nAcnD3vIyM3AbPOaTgcqrh0AqPSx7U53UFu3M6k1TH1u/eXc9/h4jm/3mpP1WRUpevlPY4PACd7AWw==", + "path": "system.text.json/4.7.0", + "hashPath": "system.text.json.4.7.0.nupkg.sha512" + }, + "Prise.IntegrationTestsContract/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "Prise.Plugin/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "XmlSerializerLib/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + } + } +} \ No newline at end of file diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginF/PluginF.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginF/PluginF.dll new file mode 100644 index 0000000..fca8e26 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginF/PluginF.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginF/PluginF.pdb b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginF/PluginF.pdb new file mode 100644 index 0000000..fe46468 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginF/PluginF.pdb differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginF/Prise.IntegrationTestsContract.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginF/Prise.IntegrationTestsContract.dll new file mode 100644 index 0000000..0b8c181 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginF/Prise.IntegrationTestsContract.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginF/Prise.IntegrationTestsContract.pdb b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginF/Prise.IntegrationTestsContract.pdb new file mode 100644 index 0000000..dce1764 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginF/Prise.IntegrationTestsContract.pdb differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginF/Prise.Plugin.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginF/Prise.Plugin.dll new file mode 100644 index 0000000..bd80490 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginF/Prise.Plugin.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginF/Prise.Plugin.pdb b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginF/Prise.Plugin.pdb new file mode 100644 index 0000000..ae9bf94 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginF/Prise.Plugin.pdb differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginF/XmlSerializerLib.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginF/XmlSerializerLib.dll new file mode 100644 index 0000000..862f0a6 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginF/XmlSerializerLib.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginF/XmlSerializerLib.pdb b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginF/XmlSerializerLib.pdb new file mode 100644 index 0000000..8f16c2f Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginF/XmlSerializerLib.pdb differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginG.1.0.0.nupkg b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginG.1.0.0.nupkg new file mode 100644 index 0000000..fef9f0c Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginG.1.0.0.nupkg differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginG/Dictionary.Domain.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginG/Dictionary.Domain.dll new file mode 100644 index 0000000..e7075ea Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginG/Dictionary.Domain.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginG/Dictionary.Domain.pdb b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginG/Dictionary.Domain.pdb new file mode 100644 index 0000000..f337317 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginG/Dictionary.Domain.pdb differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginG/ExternalServiceForPluginD.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginG/ExternalServiceForPluginD.dll new file mode 100644 index 0000000..782bc41 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginG/ExternalServiceForPluginD.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginG/ExternalServiceForPluginD.pdb b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginG/ExternalServiceForPluginD.pdb new file mode 100644 index 0000000..983622a Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginG/ExternalServiceForPluginD.pdb differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginG/Microsoft.Extensions.Configuration.Abstractions.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginG/Microsoft.Extensions.Configuration.Abstractions.dll new file mode 100644 index 0000000..52befe9 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginG/Microsoft.Extensions.Configuration.Abstractions.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginG/Microsoft.Extensions.DependencyInjection.Abstractions.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginG/Microsoft.Extensions.DependencyInjection.Abstractions.dll new file mode 100644 index 0000000..d899b25 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginG/Microsoft.Extensions.DependencyInjection.Abstractions.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginG/Microsoft.Extensions.DependencyInjection.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginG/Microsoft.Extensions.DependencyInjection.dll new file mode 100644 index 0000000..e2caf09 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginG/Microsoft.Extensions.DependencyInjection.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginG/Microsoft.Extensions.Primitives.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginG/Microsoft.Extensions.Primitives.dll new file mode 100644 index 0000000..d12ec5b Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginG/Microsoft.Extensions.Primitives.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginG/Newtonsoft.Json.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginG/Newtonsoft.Json.dll new file mode 100644 index 0000000..e2118f9 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginG/Newtonsoft.Json.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginG/PluginG.deps.json b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginG/PluginG.deps.json new file mode 100644 index 0000000..16da78b --- /dev/null +++ b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginG/PluginG.deps.json @@ -0,0 +1,168 @@ +{ + "runtimeTarget": { + "name": ".NETCoreApp,Version=v3.1", + "signature": "" + }, + "compilationOptions": {}, + "targets": { + ".NETCoreApp,Version=v3.1": { + "PluginG/1.0.0": { + "dependencies": { + "Dictionary.Domain": "1.0.0", + "ExternalServiceForPluginD": "1.0.0", + "Microsoft.Extensions.Configuration.Abstractions": "3.1.0", + "Prise.IntegrationTestsContract": "1.0.0", + "Prise.Plugin": "1.0.0", + "Prise.PluginBridge": "1.0.0" + }, + "runtime": { + "PluginG.dll": {} + } + }, + "Microsoft.Extensions.Configuration.Abstractions/3.1.0": { + "dependencies": { + "Microsoft.Extensions.Primitives": "3.1.0" + }, + "runtime": { + "lib/netcoreapp3.1/Microsoft.Extensions.Configuration.Abstractions.dll": { + "assemblyVersion": "3.1.0.0", + "fileVersion": "3.100.19.56504" + } + } + }, + "Microsoft.Extensions.DependencyInjection/3.0.0": { + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "3.0.0" + }, + "runtime": { + "lib/netcoreapp3.0/Microsoft.Extensions.DependencyInjection.dll": { + "assemblyVersion": "3.0.0.0", + "fileVersion": "3.0.19.46305" + } + } + }, + "Microsoft.Extensions.DependencyInjection.Abstractions/3.0.0": { + "runtime": { + "lib/netstandard2.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll": { + "assemblyVersion": "3.0.0.0", + "fileVersion": "3.0.19.46305" + } + } + }, + "Microsoft.Extensions.Primitives/3.1.0": { + "runtime": { + "lib/netcoreapp3.1/Microsoft.Extensions.Primitives.dll": { + "assemblyVersion": "3.1.0.0", + "fileVersion": "3.100.19.56504" + } + } + }, + "Newtonsoft.Json/11.0.2": { + "runtime": { + "lib/netstandard2.0/Newtonsoft.Json.dll": { + "assemblyVersion": "11.0.0.0", + "fileVersion": "11.0.2.21924" + } + } + }, + "Dictionary.Domain/1.0.0": { + "dependencies": { + "Newtonsoft.Json": "11.0.2" + }, + "runtime": { + "Dictionary.Domain.dll": {} + } + }, + "ExternalServiceForPluginD/1.0.0": { + "runtime": { + "ExternalServiceForPluginD.dll": {} + } + }, + "Prise.IntegrationTestsContract/1.0.0": { + "runtime": { + "Prise.IntegrationTestsContract.dll": {} + } + }, + "Prise.Plugin/1.0.0": { + "dependencies": { + "Microsoft.Extensions.DependencyInjection": "3.0.0" + }, + "runtime": { + "Prise.Plugin.dll": {} + } + }, + "Prise.PluginBridge/1.0.0": { + "runtime": { + "Prise.PluginBridge.dll": {} + } + } + } + }, + "libraries": { + "PluginG/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "Microsoft.Extensions.Configuration.Abstractions/3.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-ESz6bVoDQX7sgWdKHF6G9Pq672T8k+19AFb/txDXwdz7MoqaNQj2/in3agm/3qae9V+WvQZH86LLTNVo0it8vQ==", + "path": "microsoft.extensions.configuration.abstractions/3.1.0", + "hashPath": "microsoft.extensions.configuration.abstractions.3.1.0.nupkg.sha512" + }, + "Microsoft.Extensions.DependencyInjection/3.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-yDsuNA/BT4j9qrcRs0NUNHQAJfywFWX18ZZ+shxXJL+/nIfz3vhuRTfnYgvFeQlNBlgmgdSjOcs4ajgoS6Q/Ng==", + "path": "microsoft.extensions.dependencyinjection/3.0.0", + "hashPath": "microsoft.extensions.dependencyinjection.3.0.0.nupkg.sha512" + }, + "Microsoft.Extensions.DependencyInjection.Abstractions/3.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-ofQRroDlzJ0xKOtzNuaVt6QKNImFkhkG0lIMpGl7PtXnIf5SuLWBeiQZAP8DNSxDBJJdcsPkiJiMYK2WA5H8dQ==", + "path": "microsoft.extensions.dependencyinjection.abstractions/3.0.0", + "hashPath": "microsoft.extensions.dependencyinjection.abstractions.3.0.0.nupkg.sha512" + }, + "Microsoft.Extensions.Primitives/3.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-LEKAnX7lhUhSoIc2XraCTK3M4IU/LdVUzCe464Sa4+7F4ZJuXHHRzZli2mDbiT4xzAZhgqXbvfnb5+CNDcQFfg==", + "path": "microsoft.extensions.primitives/3.1.0", + "hashPath": "microsoft.extensions.primitives.3.1.0.nupkg.sha512" + }, + "Newtonsoft.Json/11.0.2": { + "type": "package", + "serviceable": true, + "sha512": "sha512-IvJe1pj7JHEsP8B8J8DwlMEx8UInrs/x+9oVY+oCD13jpLu4JbJU2WCIsMRn5C4yW9+DgkaO8uiVE5VHKjpmdQ==", + "path": "newtonsoft.json/11.0.2", + "hashPath": "newtonsoft.json.11.0.2.nupkg.sha512" + }, + "Dictionary.Domain/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "ExternalServiceForPluginD/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "Prise.IntegrationTestsContract/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "Prise.Plugin/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "Prise.PluginBridge/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + } + } +} \ No newline at end of file diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginG/PluginG.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginG/PluginG.dll new file mode 100644 index 0000000..94582f8 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginG/PluginG.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginG/PluginG.pdb b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginG/PluginG.pdb new file mode 100644 index 0000000..9108a1a Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginG/PluginG.pdb differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginG/Prise.IntegrationTestsContract.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginG/Prise.IntegrationTestsContract.dll new file mode 100644 index 0000000..5cdfe44 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginG/Prise.IntegrationTestsContract.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginG/Prise.IntegrationTestsContract.pdb b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginG/Prise.IntegrationTestsContract.pdb new file mode 100644 index 0000000..261bf1d Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginG/Prise.IntegrationTestsContract.pdb differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginG/Prise.Plugin.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginG/Prise.Plugin.dll new file mode 100644 index 0000000..30afb86 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginG/Prise.Plugin.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginG/Prise.Plugin.pdb b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginG/Prise.Plugin.pdb new file mode 100644 index 0000000..7c30993 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginG/Prise.Plugin.pdb differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginG/Prise.PluginBridge.dll b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginG/Prise.PluginBridge.dll new file mode 100644 index 0000000..a8a092d Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginG/Prise.PluginBridge.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginG/Prise.PluginBridge.pdb b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginG/Prise.PluginBridge.pdb new file mode 100644 index 0000000..b4701c3 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netcoreapp3.1/PluginG/Prise.PluginBridge.pdb differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/Legacy.Contract.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/Legacy.Contract.dll new file mode 100644 index 0000000..52bf1a0 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/Legacy.Contract.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/Legacy.Domain.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/Legacy.Domain.dll new file mode 100644 index 0000000..077efeb Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/Legacy.Domain.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/Legacy.Domain.pdb b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/Legacy.Domain.pdb new file mode 100644 index 0000000..4323ec6 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/Legacy.Domain.pdb differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/LegacyPlugin.deps.json b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/LegacyPlugin.deps.json new file mode 100644 index 0000000..78a8e9a --- /dev/null +++ b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/LegacyPlugin.deps.json @@ -0,0 +1,915 @@ +{ + "runtimeTarget": { + "name": ".NETStandard,Version=v2.0/", + "signature": "" + }, + "compilationOptions": {}, + "targets": { + ".NETStandard,Version=v2.0": {}, + ".NETStandard,Version=v2.0/": { + "LegacyPlugin/1.0.0": { + "dependencies": { + "Legacy.Domain": "1.0.0", + "Microsoft.Extensions.Configuration.Abstractions": "2.1.1", + "NETStandard.Library": "2.0.3", + "Prise.Plugin": "1.4.2", + "Legacy.Contract": "1.0.0.0" + }, + "runtime": { + "LegacyPlugin.dll": {} + } + }, + "Microsoft.CSharp/4.0.1": { + "dependencies": { + "System.Collections": "4.0.11", + "System.Diagnostics.Debug": "4.0.11", + "System.Dynamic.Runtime": "4.0.11", + "System.Globalization": "4.0.11", + "System.Linq": "4.1.0", + "System.Linq.Expressions": "4.1.0", + "System.ObjectModel": "4.0.12", + "System.Reflection": "4.1.0", + "System.Reflection.Extensions": "4.0.1", + "System.Reflection.Primitives": "4.0.1", + "System.Reflection.TypeExtensions": "4.1.0", + "System.Resources.ResourceManager": "4.0.1", + "System.Runtime": "4.1.0", + "System.Runtime.Extensions": "4.1.0", + "System.Runtime.InteropServices": "4.1.0", + "System.Threading": "4.0.11" + }, + "runtime": { + "lib/netstandard1.3/Microsoft.CSharp.dll": { + "assemblyVersion": "4.0.1.0", + "fileVersion": "1.0.24212.1" + } + } + }, + "Microsoft.Extensions.Configuration.Abstractions/2.1.1": { + "dependencies": { + "Microsoft.Extensions.Primitives": "2.1.1" + }, + "runtime": { + "lib/netstandard2.0/Microsoft.Extensions.Configuration.Abstractions.dll": { + "assemblyVersion": "2.1.1.0", + "fileVersion": "2.1.1.18157" + } + } + }, + "Microsoft.Extensions.DependencyInjection/2.1.0": { + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "2.1.0" + }, + "runtime": { + "lib/netstandard2.0/Microsoft.Extensions.DependencyInjection.dll": { + "assemblyVersion": "2.1.0.0", + "fileVersion": "2.1.0.18136" + } + } + }, + "Microsoft.Extensions.DependencyInjection.Abstractions/2.1.0": { + "runtime": { + "lib/netstandard2.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll": { + "assemblyVersion": "2.1.0.0", + "fileVersion": "2.1.0.18136" + } + } + }, + "Microsoft.Extensions.Primitives/2.1.1": { + "dependencies": { + "System.Memory": "4.5.1", + "System.Runtime.CompilerServices.Unsafe": "4.5.1" + }, + "runtime": { + "lib/netstandard2.0/Microsoft.Extensions.Primitives.dll": { + "assemblyVersion": "2.1.1.0", + "fileVersion": "2.1.1.18157" + } + } + }, + "Microsoft.NETCore.Platforms/1.1.0": {}, + "Microsoft.NETCore.Targets/1.0.1": {}, + "NETStandard.Library/2.0.3": { + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0" + } + }, + "Newtonsoft.Json/9.0.1": { + "dependencies": { + "Microsoft.CSharp": "4.0.1", + "System.Collections": "4.0.11", + "System.Diagnostics.Debug": "4.0.11", + "System.Dynamic.Runtime": "4.0.11", + "System.Globalization": "4.0.11", + "System.IO": "4.1.0", + "System.Linq": "4.1.0", + "System.Linq.Expressions": "4.1.0", + "System.ObjectModel": "4.0.12", + "System.Reflection": "4.1.0", + "System.Reflection.Extensions": "4.0.1", + "System.Resources.ResourceManager": "4.0.1", + "System.Runtime": "4.1.0", + "System.Runtime.Extensions": "4.1.0", + "System.Runtime.Serialization.Primitives": "4.1.1", + "System.Text.Encoding": "4.0.11", + "System.Text.Encoding.Extensions": "4.0.11", + "System.Text.RegularExpressions": "4.1.0", + "System.Threading": "4.0.11", + "System.Threading.Tasks": "4.0.11", + "System.Xml.ReaderWriter": "4.0.11", + "System.Xml.XDocument": "4.0.11" + }, + "runtime": { + "lib/netstandard1.0/Newtonsoft.Json.dll": { + "assemblyVersion": "9.0.0.0", + "fileVersion": "9.0.1.19813" + } + } + }, + "Prise.Plugin/1.4.2": { + "dependencies": { + "Microsoft.Extensions.DependencyInjection": "2.1.0" + }, + "runtime": { + "lib/netstandard2.0/Prise.Plugin.dll": { + "assemblyVersion": "1.4.2.0", + "fileVersion": "1.4.2.0" + } + } + }, + "System.Buffers/4.4.0": { + "runtime": { + "lib/netstandard2.0/System.Buffers.dll": { + "assemblyVersion": "4.0.2.0", + "fileVersion": "4.6.25519.3" + } + } + }, + "System.Collections/4.0.11": { + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.0.1", + "System.Runtime": "4.1.0" + } + }, + "System.Diagnostics.Debug/4.0.11": { + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.0.1", + "System.Runtime": "4.1.0" + } + }, + "System.Diagnostics.Tools/4.0.1": { + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.0.1", + "System.Runtime": "4.1.0" + } + }, + "System.Dynamic.Runtime/4.0.11": { + "dependencies": { + "System.Collections": "4.0.11", + "System.Diagnostics.Debug": "4.0.11", + "System.Globalization": "4.0.11", + "System.Linq": "4.1.0", + "System.Linq.Expressions": "4.1.0", + "System.ObjectModel": "4.0.12", + "System.Reflection": "4.1.0", + "System.Reflection.Emit": "4.0.1", + "System.Reflection.Emit.ILGeneration": "4.0.1", + "System.Reflection.Primitives": "4.0.1", + "System.Reflection.TypeExtensions": "4.1.0", + "System.Resources.ResourceManager": "4.0.1", + "System.Runtime": "4.1.0", + "System.Runtime.Extensions": "4.1.0", + "System.Threading": "4.0.11" + }, + "runtime": { + "lib/netstandard1.3/System.Dynamic.Runtime.dll": { + "assemblyVersion": "4.0.11.0", + "fileVersion": "1.0.24212.1" + } + } + }, + "System.Globalization/4.0.11": { + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.0.1", + "System.Runtime": "4.1.0" + } + }, + "System.IO/4.1.0": { + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.0.1", + "System.Runtime": "4.1.0", + "System.Text.Encoding": "4.0.11", + "System.Threading.Tasks": "4.0.11" + } + }, + "System.IO.FileSystem/4.0.1": { + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.0.1", + "System.IO": "4.1.0", + "System.IO.FileSystem.Primitives": "4.0.1", + "System.Runtime": "4.1.0", + "System.Runtime.Handles": "4.0.1", + "System.Text.Encoding": "4.0.11", + "System.Threading.Tasks": "4.0.11" + } + }, + "System.IO.FileSystem.Primitives/4.0.1": { + "dependencies": { + "System.Runtime": "4.1.0" + }, + "runtime": { + "lib/netstandard1.3/System.IO.FileSystem.Primitives.dll": { + "assemblyVersion": "4.0.1.0", + "fileVersion": "1.0.24212.1" + } + } + }, + "System.Linq/4.1.0": { + "dependencies": { + "System.Collections": "4.0.11", + "System.Diagnostics.Debug": "4.0.11", + "System.Resources.ResourceManager": "4.0.1", + "System.Runtime": "4.1.0", + "System.Runtime.Extensions": "4.1.0" + }, + "runtime": { + "lib/netstandard1.6/System.Linq.dll": { + "assemblyVersion": "4.1.0.0", + "fileVersion": "1.0.24212.1" + } + } + }, + "System.Linq.Expressions/4.1.0": { + "dependencies": { + "System.Collections": "4.0.11", + "System.Diagnostics.Debug": "4.0.11", + "System.Globalization": "4.0.11", + "System.IO": "4.1.0", + "System.Linq": "4.1.0", + "System.ObjectModel": "4.0.12", + "System.Reflection": "4.1.0", + "System.Reflection.Emit": "4.0.1", + "System.Reflection.Emit.ILGeneration": "4.0.1", + "System.Reflection.Emit.Lightweight": "4.0.1", + "System.Reflection.Extensions": "4.0.1", + "System.Reflection.Primitives": "4.0.1", + "System.Reflection.TypeExtensions": "4.1.0", + "System.Resources.ResourceManager": "4.0.1", + "System.Runtime": "4.1.0", + "System.Runtime.Extensions": "4.1.0", + "System.Threading": "4.0.11" + }, + "runtime": { + "lib/netstandard1.6/System.Linq.Expressions.dll": { + "assemblyVersion": "4.1.0.0", + "fileVersion": "1.0.24212.1" + } + } + }, + "System.Memory/4.5.1": { + "dependencies": { + "System.Buffers": "4.4.0", + "System.Numerics.Vectors": "4.4.0", + "System.Runtime.CompilerServices.Unsafe": "4.5.1" + }, + "runtime": { + "lib/netstandard2.0/System.Memory.dll": { + "assemblyVersion": "4.0.1.0", + "fileVersion": "4.6.26606.5" + } + } + }, + "System.Numerics.Vectors/4.4.0": { + "runtime": { + "lib/netstandard2.0/System.Numerics.Vectors.dll": { + "assemblyVersion": "4.1.3.0", + "fileVersion": "4.6.25519.3" + } + } + }, + "System.ObjectModel/4.0.12": { + "dependencies": { + "System.Collections": "4.0.11", + "System.Diagnostics.Debug": "4.0.11", + "System.Resources.ResourceManager": "4.0.1", + "System.Runtime": "4.1.0", + "System.Threading": "4.0.11" + }, + "runtime": { + "lib/netstandard1.3/System.ObjectModel.dll": { + "assemblyVersion": "4.0.12.0", + "fileVersion": "1.0.24212.1" + } + } + }, + "System.Reflection/4.1.0": { + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.0.1", + "System.IO": "4.1.0", + "System.Reflection.Primitives": "4.0.1", + "System.Runtime": "4.1.0" + } + }, + "System.Reflection.Emit/4.0.1": { + "dependencies": { + "System.IO": "4.1.0", + "System.Reflection": "4.1.0", + "System.Reflection.Emit.ILGeneration": "4.0.1", + "System.Reflection.Primitives": "4.0.1", + "System.Runtime": "4.1.0" + }, + "runtime": { + "lib/netstandard1.3/System.Reflection.Emit.dll": { + "assemblyVersion": "4.0.1.0", + "fileVersion": "1.0.24212.1" + } + } + }, + "System.Reflection.Emit.ILGeneration/4.0.1": { + "dependencies": { + "System.Reflection": "4.1.0", + "System.Reflection.Primitives": "4.0.1", + "System.Runtime": "4.1.0" + }, + "runtime": { + "lib/netstandard1.3/System.Reflection.Emit.ILGeneration.dll": { + "assemblyVersion": "4.0.1.0", + "fileVersion": "1.0.24212.1" + } + } + }, + "System.Reflection.Emit.Lightweight/4.0.1": { + "dependencies": { + "System.Reflection": "4.1.0", + "System.Reflection.Emit.ILGeneration": "4.0.1", + "System.Reflection.Primitives": "4.0.1", + "System.Runtime": "4.1.0" + }, + "runtime": { + "lib/netstandard1.3/System.Reflection.Emit.Lightweight.dll": { + "assemblyVersion": "4.0.1.0", + "fileVersion": "1.0.24212.1" + } + } + }, + "System.Reflection.Extensions/4.0.1": { + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.0.1", + "System.Reflection": "4.1.0", + "System.Runtime": "4.1.0" + } + }, + "System.Reflection.Primitives/4.0.1": { + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.0.1", + "System.Runtime": "4.1.0" + } + }, + "System.Reflection.TypeExtensions/4.1.0": { + "dependencies": { + "System.Reflection": "4.1.0", + "System.Runtime": "4.1.0" + }, + "runtime": { + "lib/netstandard1.5/System.Reflection.TypeExtensions.dll": { + "assemblyVersion": "4.1.0.0", + "fileVersion": "1.0.24212.1" + } + } + }, + "System.Resources.ResourceManager/4.0.1": { + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.0.1", + "System.Globalization": "4.0.11", + "System.Reflection": "4.1.0", + "System.Runtime": "4.1.0" + } + }, + "System.Runtime/4.1.0": { + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.0.1" + } + }, + "System.Runtime.CompilerServices.Unsafe/4.5.1": { + "runtime": { + "lib/netstandard2.0/System.Runtime.CompilerServices.Unsafe.dll": { + "assemblyVersion": "4.0.4.0", + "fileVersion": "0.0.0.0" + } + } + }, + "System.Runtime.Extensions/4.1.0": { + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.0.1", + "System.Runtime": "4.1.0" + } + }, + "System.Runtime.Handles/4.0.1": { + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.0.1", + "System.Runtime": "4.1.0" + } + }, + "System.Runtime.InteropServices/4.1.0": { + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.0.1", + "System.Reflection": "4.1.0", + "System.Reflection.Primitives": "4.0.1", + "System.Runtime": "4.1.0", + "System.Runtime.Handles": "4.0.1" + } + }, + "System.Runtime.Serialization.Primitives/4.1.1": { + "dependencies": { + "System.Resources.ResourceManager": "4.0.1", + "System.Runtime": "4.1.0" + }, + "runtime": { + "lib/netstandard1.3/System.Runtime.Serialization.Primitives.dll": { + "assemblyVersion": "4.1.1.0", + "fileVersion": "1.0.24212.1" + } + } + }, + "System.Text.Encoding/4.0.11": { + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.0.1", + "System.Runtime": "4.1.0" + } + }, + "System.Text.Encoding.Extensions/4.0.11": { + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.0.1", + "System.Runtime": "4.1.0", + "System.Text.Encoding": "4.0.11" + } + }, + "System.Text.RegularExpressions/4.1.0": { + "dependencies": { + "System.Collections": "4.0.11", + "System.Globalization": "4.0.11", + "System.Resources.ResourceManager": "4.0.1", + "System.Runtime": "4.1.0", + "System.Runtime.Extensions": "4.1.0", + "System.Threading": "4.0.11" + }, + "runtime": { + "lib/netstandard1.6/System.Text.RegularExpressions.dll": { + "assemblyVersion": "4.1.0.0", + "fileVersion": "1.0.24212.1" + } + } + }, + "System.Threading/4.0.11": { + "dependencies": { + "System.Runtime": "4.1.0", + "System.Threading.Tasks": "4.0.11" + }, + "runtime": { + "lib/netstandard1.3/System.Threading.dll": { + "assemblyVersion": "4.0.11.0", + "fileVersion": "1.0.24212.1" + } + } + }, + "System.Threading.Tasks/4.0.11": { + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.0.1", + "System.Runtime": "4.1.0" + } + }, + "System.Threading.Tasks.Extensions/4.0.0": { + "dependencies": { + "System.Collections": "4.0.11", + "System.Runtime": "4.1.0", + "System.Threading.Tasks": "4.0.11" + }, + "runtime": { + "lib/netstandard1.0/System.Threading.Tasks.Extensions.dll": { + "assemblyVersion": "4.0.0.0", + "fileVersion": "1.0.24212.1" + } + } + }, + "System.Xml.ReaderWriter/4.0.11": { + "dependencies": { + "System.Collections": "4.0.11", + "System.Diagnostics.Debug": "4.0.11", + "System.Globalization": "4.0.11", + "System.IO": "4.1.0", + "System.IO.FileSystem": "4.0.1", + "System.IO.FileSystem.Primitives": "4.0.1", + "System.Resources.ResourceManager": "4.0.1", + "System.Runtime": "4.1.0", + "System.Runtime.Extensions": "4.1.0", + "System.Runtime.InteropServices": "4.1.0", + "System.Text.Encoding": "4.0.11", + "System.Text.Encoding.Extensions": "4.0.11", + "System.Text.RegularExpressions": "4.1.0", + "System.Threading.Tasks": "4.0.11", + "System.Threading.Tasks.Extensions": "4.0.0" + }, + "runtime": { + "lib/netstandard1.3/System.Xml.ReaderWriter.dll": { + "assemblyVersion": "4.0.11.0", + "fileVersion": "1.0.24212.1" + } + } + }, + "System.Xml.XDocument/4.0.11": { + "dependencies": { + "System.Collections": "4.0.11", + "System.Diagnostics.Debug": "4.0.11", + "System.Diagnostics.Tools": "4.0.1", + "System.Globalization": "4.0.11", + "System.IO": "4.1.0", + "System.Reflection": "4.1.0", + "System.Resources.ResourceManager": "4.0.1", + "System.Runtime": "4.1.0", + "System.Runtime.Extensions": "4.1.0", + "System.Text.Encoding": "4.0.11", + "System.Threading": "4.0.11", + "System.Xml.ReaderWriter": "4.0.11" + }, + "runtime": { + "lib/netstandard1.3/System.Xml.XDocument.dll": { + "assemblyVersion": "4.0.11.0", + "fileVersion": "1.0.24212.1" + } + } + }, + "Legacy.Domain/1.0.0": { + "dependencies": { + "Newtonsoft.Json": "9.0.1" + }, + "runtime": { + "Legacy.Domain.dll": {} + } + }, + "Legacy.Contract/1.0.0.0": { + "runtime": { + "Legacy.Contract.dll": { + "assemblyVersion": "1.0.0.0", + "fileVersion": "1.0.0.0" + } + } + } + } + }, + "libraries": { + "LegacyPlugin/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "Microsoft.CSharp/4.0.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-17h8b5mXa87XYKrrVqdgZ38JefSUqLChUQpXgSnpzsM0nDOhE40FTeNWOJ/YmySGV6tG6T8+hjz6vxbknHJr6A==", + "path": "microsoft.csharp/4.0.1", + "hashPath": "microsoft.csharp.4.0.1.nupkg.sha512" + }, + "Microsoft.Extensions.Configuration.Abstractions/2.1.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-VfuZJNa0WUshZ/+8BFZAhwFKiKuu/qOUCFntfdLpHj7vcRnsGHqd3G2Hse78DM+pgozczGM63lGPRLmy+uhUOA==", + "path": "microsoft.extensions.configuration.abstractions/2.1.1", + "hashPath": "microsoft.extensions.configuration.abstractions.2.1.1.nupkg.sha512" + }, + "Microsoft.Extensions.DependencyInjection/2.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-gqQviLfuA31PheEGi+XJoZc1bc9H9RsPa9Gq9XuDct7XGWSR9eVXjK5Sg7CSUPhTFHSuxUFY12wcTYLZ4zM1hg==", + "path": "microsoft.extensions.dependencyinjection/2.1.0", + "hashPath": "microsoft.extensions.dependencyinjection.2.1.0.nupkg.sha512" + }, + "Microsoft.Extensions.DependencyInjection.Abstractions/2.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-8/CtASu80UIoyG+r8FstrmZW5GLtXxzoYpjj3jV0FKZCL5CiFgSH3pAmqut/dC68mu7N1bU6v0UtKKL3gCUQGQ==", + "path": "microsoft.extensions.dependencyinjection.abstractions/2.1.0", + "hashPath": "microsoft.extensions.dependencyinjection.abstractions.2.1.0.nupkg.sha512" + }, + "Microsoft.Extensions.Primitives/2.1.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-scJ1GZNIxMmjpENh0UZ8XCQ6vzr/LzeF9WvEA51Ix2OQGAs9WPgPu8ABVUdvpKPLuor/t05gm6menJK3PwqOXg==", + "path": "microsoft.extensions.primitives/2.1.1", + "hashPath": "microsoft.extensions.primitives.2.1.1.nupkg.sha512" + }, + "Microsoft.NETCore.Platforms/1.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-kz0PEW2lhqygehI/d6XsPCQzD7ff7gUJaVGPVETX611eadGsA3A877GdSlU0LRVMCTH/+P3o2iDTak+S08V2+A==", + "path": "microsoft.netcore.platforms/1.1.0", + "hashPath": "microsoft.netcore.platforms.1.1.0.nupkg.sha512" + }, + "Microsoft.NETCore.Targets/1.0.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-rkn+fKobF/cbWfnnfBOQHKVKIOpxMZBvlSHkqDWgBpwGDcLRduvs3D9OLGeV6GWGvVwNlVi2CBbTjuPmtHvyNw==", + "path": "microsoft.netcore.targets/1.0.1", + "hashPath": "microsoft.netcore.targets.1.0.1.nupkg.sha512" + }, + "NETStandard.Library/2.0.3": { + "type": "package", + "serviceable": true, + "sha512": "sha512-st47PosZSHrjECdjeIzZQbzivYBJFv6P2nv4cj2ypdI204DO+vZ7l5raGMiX4eXMJ53RfOIg+/s4DHVZ54Nu2A==", + "path": "netstandard.library/2.0.3", + "hashPath": "netstandard.library.2.0.3.nupkg.sha512" + }, + "Newtonsoft.Json/9.0.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-U82mHQSKaIk+lpSVCbWYKNavmNH1i5xrExDEquU1i6I5pV6UMOqRnJRSlKO3cMPfcpp0RgDY+8jUXHdQ4IfXvw==", + "path": "newtonsoft.json/9.0.1", + "hashPath": "newtonsoft.json.9.0.1.nupkg.sha512" + }, + "Prise.Plugin/1.4.2": { + "type": "package", + "serviceable": true, + "sha512": "sha512-Uhbdd/HTbCAsSqhSSLM1cvMS3E244yBSUWv6DR8QT72BzE2HDVII8ejLZ4rBuz1kXB0GtIJ8ZoA5mASVWh+lZA==", + "path": "prise.plugin/1.4.2", + "hashPath": "prise.plugin.1.4.2.nupkg.sha512" + }, + "System.Buffers/4.4.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-AwarXzzoDwX6BgrhjoJsk6tUezZEozOT5Y9QKF94Gl4JK91I4PIIBkBco9068Y9/Dra8Dkbie99kXB8+1BaYKw==", + "path": "system.buffers/4.4.0", + "hashPath": "system.buffers.4.4.0.nupkg.sha512" + }, + "System.Collections/4.0.11": { + "type": "package", + "serviceable": true, + "sha512": "sha512-YUJGz6eFKqS0V//mLt25vFGrrCvOnsXjlvFQs+KimpwNxug9x0Pzy4PlFMU3Q2IzqAa9G2L4LsK3+9vCBK7oTg==", + "path": "system.collections/4.0.11", + "hashPath": "system.collections.4.0.11.nupkg.sha512" + }, + "System.Diagnostics.Debug/4.0.11": { + "type": "package", + "serviceable": true, + "sha512": "sha512-w5U95fVKHY4G8ASs/K5iK3J5LY+/dLFd4vKejsnI/ZhBsWS9hQakfx3Zr7lRWKg4tAw9r4iktyvsTagWkqYCiw==", + "path": "system.diagnostics.debug/4.0.11", + "hashPath": "system.diagnostics.debug.4.0.11.nupkg.sha512" + }, + "System.Diagnostics.Tools/4.0.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-xBfJ8pnd4C17dWaC9FM6aShzbJcRNMChUMD42I6772KGGrqaFdumwhn9OdM68erj1ueNo3xdQ1EwiFjK5k8p0g==", + "path": "system.diagnostics.tools/4.0.1", + "hashPath": "system.diagnostics.tools.4.0.1.nupkg.sha512" + }, + "System.Dynamic.Runtime/4.0.11": { + "type": "package", + "serviceable": true, + "sha512": "sha512-db34f6LHYM0U0JpE+sOmjar27BnqTVkbLJhgfwMpTdgTigG/Hna3m2MYVwnFzGGKnEJk2UXFuoVTr8WUbU91/A==", + "path": "system.dynamic.runtime/4.0.11", + "hashPath": "system.dynamic.runtime.4.0.11.nupkg.sha512" + }, + "System.Globalization/4.0.11": { + "type": "package", + "serviceable": true, + "sha512": "sha512-B95h0YLEL2oSnwF/XjqSWKnwKOy/01VWkNlsCeMTFJLLabflpGV26nK164eRs5GiaRSBGpOxQ3pKoSnnyZN5pg==", + "path": "system.globalization/4.0.11", + "hashPath": "system.globalization.4.0.11.nupkg.sha512" + }, + "System.IO/4.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-3KlTJceQc3gnGIaHZ7UBZO26SHL1SHE4ddrmiwumFnId+CEHP+O8r386tZKaE6zlk5/mF8vifMBzHj9SaXN+mQ==", + "path": "system.io/4.1.0", + "hashPath": "system.io.4.1.0.nupkg.sha512" + }, + "System.IO.FileSystem/4.0.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-IBErlVq5jOggAD69bg1t0pJcHaDbJbWNUZTPI96fkYWzwYbN6D9wRHMULLDd9dHsl7C2YsxXL31LMfPI1SWt8w==", + "path": "system.io.filesystem/4.0.1", + "hashPath": "system.io.filesystem.4.0.1.nupkg.sha512" + }, + "System.IO.FileSystem.Primitives/4.0.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-kWkKD203JJKxJeE74p8aF8y4Qc9r9WQx4C0cHzHPrY3fv/L/IhWnyCHaFJ3H1QPOH6A93whlQ2vG5nHlBDvzWQ==", + "path": "system.io.filesystem.primitives/4.0.1", + "hashPath": "system.io.filesystem.primitives.4.0.1.nupkg.sha512" + }, + "System.Linq/4.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-bQ0iYFOQI0nuTnt+NQADns6ucV4DUvMdwN6CbkB1yj8i7arTGiTN5eok1kQwdnnNWSDZfIUySQY+J3d5KjWn0g==", + "path": "system.linq/4.1.0", + "hashPath": "system.linq.4.1.0.nupkg.sha512" + }, + "System.Linq.Expressions/4.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-I+y02iqkgmCAyfbqOmSDOgqdZQ5tTj80Akm5BPSS8EeB0VGWdy6X1KCoYe8Pk6pwDoAKZUOdLVxnTJcExiv5zw==", + "path": "system.linq.expressions/4.1.0", + "hashPath": "system.linq.expressions.4.1.0.nupkg.sha512" + }, + "System.Memory/4.5.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-sDJYJpGtTgx+23Ayu5euxG5mAXWdkDb4+b0rD0Cab0M1oQS9H0HXGPriKcqpXuiJDTV7fTp/d+fMDJmnr6sNvA==", + "path": "system.memory/4.5.1", + "hashPath": "system.memory.4.5.1.nupkg.sha512" + }, + "System.Numerics.Vectors/4.4.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-UiLzLW+Lw6HLed1Hcg+8jSRttrbuXv7DANVj0DkL9g6EnnzbL75EB7EWsw5uRbhxd/4YdG8li5XizGWepmG3PQ==", + "path": "system.numerics.vectors/4.4.0", + "hashPath": "system.numerics.vectors.4.4.0.nupkg.sha512" + }, + "System.ObjectModel/4.0.12": { + "type": "package", + "serviceable": true, + "sha512": "sha512-tAgJM1xt3ytyMoW4qn4wIqgJYm7L7TShRZG4+Q4Qsi2PCcj96pXN7nRywS9KkB3p/xDUjc2HSwP9SROyPYDYKQ==", + "path": "system.objectmodel/4.0.12", + "hashPath": "system.objectmodel.4.0.12.nupkg.sha512" + }, + "System.Reflection/4.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-JCKANJ0TI7kzoQzuwB/OoJANy1Lg338B6+JVacPl4TpUwi3cReg3nMLplMq2uqYfHFQpKIlHAUVAJlImZz/4ng==", + "path": "system.reflection/4.1.0", + "hashPath": "system.reflection.4.1.0.nupkg.sha512" + }, + "System.Reflection.Emit/4.0.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-P2wqAj72fFjpP6wb9nSfDqNBMab+2ovzSDzUZK7MVIm54tBJEPr9jWfSjjoTpPwj1LeKcmX3vr0ttyjSSFM47g==", + "path": "system.reflection.emit/4.0.1", + "hashPath": "system.reflection.emit.4.0.1.nupkg.sha512" + }, + "System.Reflection.Emit.ILGeneration/4.0.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-Ov6dU8Bu15Bc7zuqttgHF12J5lwSWyTf1S+FJouUXVMSqImLZzYaQ+vRr1rQ0OZ0HqsrwWl4dsKHELckQkVpgA==", + "path": "system.reflection.emit.ilgeneration/4.0.1", + "hashPath": "system.reflection.emit.ilgeneration.4.0.1.nupkg.sha512" + }, + "System.Reflection.Emit.Lightweight/4.0.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-sSzHHXueZ5Uh0OLpUQprhr+ZYJrLPA2Cmr4gn0wj9+FftNKXx8RIMKvO9qnjk2ebPYUjZ+F2ulGdPOsvj+MEjA==", + "path": "system.reflection.emit.lightweight/4.0.1", + "hashPath": "system.reflection.emit.lightweight.4.0.1.nupkg.sha512" + }, + "System.Reflection.Extensions/4.0.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-GYrtRsZcMuHF3sbmRHfMYpvxZoIN2bQGrYGerUiWLEkqdEUQZhH3TRSaC/oI4wO0II1RKBPlpIa1TOMxIcOOzQ==", + "path": "system.reflection.extensions/4.0.1", + "hashPath": "system.reflection.extensions.4.0.1.nupkg.sha512" + }, + "System.Reflection.Primitives/4.0.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-4inTox4wTBaDhB7V3mPvp9XlCbeGYWVEM9/fXALd52vNEAVisc1BoVWQPuUuD0Ga//dNbA/WeMy9u9mzLxGTHQ==", + "path": "system.reflection.primitives/4.0.1", + "hashPath": "system.reflection.primitives.4.0.1.nupkg.sha512" + }, + "System.Reflection.TypeExtensions/4.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-tsQ/ptQ3H5FYfON8lL4MxRk/8kFyE0A+tGPXmVP967cT/gzLHYxIejIYSxp4JmIeFHVP78g/F2FE1mUUTbDtrg==", + "path": "system.reflection.typeextensions/4.1.0", + "hashPath": "system.reflection.typeextensions.4.1.0.nupkg.sha512" + }, + "System.Resources.ResourceManager/4.0.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-TxwVeUNoTgUOdQ09gfTjvW411MF+w9MBYL7AtNVc+HtBCFlutPLhUCdZjNkjbhj3bNQWMdHboF0KIWEOjJssbA==", + "path": "system.resources.resourcemanager/4.0.1", + "hashPath": "system.resources.resourcemanager.4.0.1.nupkg.sha512" + }, + "System.Runtime/4.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-v6c/4Yaa9uWsq+JMhnOFewrYkgdNHNG2eMKuNqRn8P733rNXeRCGvV5FkkjBXn2dbVkPXOsO0xjsEeM1q2zC0g==", + "path": "system.runtime/4.1.0", + "hashPath": "system.runtime.4.1.0.nupkg.sha512" + }, + "System.Runtime.CompilerServices.Unsafe/4.5.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-Zh8t8oqolRaFa9vmOZfdQm/qKejdqz0J9kr7o2Fu0vPeoH3BL1EOXipKWwkWtLT1JPzjByrF19fGuFlNbmPpiw==", + "path": "system.runtime.compilerservices.unsafe/4.5.1", + "hashPath": "system.runtime.compilerservices.unsafe.4.5.1.nupkg.sha512" + }, + "System.Runtime.Extensions/4.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-CUOHjTT/vgP0qGW22U4/hDlOqXmcPq5YicBaXdUR2UiUoLwBT+olO6we4DVbq57jeX5uXH2uerVZhf0qGj+sVQ==", + "path": "system.runtime.extensions/4.1.0", + "hashPath": "system.runtime.extensions.4.1.0.nupkg.sha512" + }, + "System.Runtime.Handles/4.0.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-nCJvEKguXEvk2ymk1gqj625vVnlK3/xdGzx0vOKicQkoquaTBJTP13AIYkocSUwHCLNBwUbXTqTWGDxBTWpt7g==", + "path": "system.runtime.handles/4.0.1", + "hashPath": "system.runtime.handles.4.0.1.nupkg.sha512" + }, + "System.Runtime.InteropServices/4.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-16eu3kjHS633yYdkjwShDHZLRNMKVi/s0bY8ODiqJ2RfMhDMAwxZaUaWVnZ2P71kr/or+X9o/xFWtNqz8ivieQ==", + "path": "system.runtime.interopservices/4.1.0", + "hashPath": "system.runtime.interopservices.4.1.0.nupkg.sha512" + }, + "System.Runtime.Serialization.Primitives/4.1.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-HZ6Du5QrTG8MNJbf4e4qMO3JRAkIboGT5Fk804uZtg3Gq516S7hAqTm2UZKUHa7/6HUGdVy3AqMQKbns06G/cg==", + "path": "system.runtime.serialization.primitives/4.1.1", + "hashPath": "system.runtime.serialization.primitives.4.1.1.nupkg.sha512" + }, + "System.Text.Encoding/4.0.11": { + "type": "package", + "serviceable": true, + "sha512": "sha512-U3gGeMlDZXxCEiY4DwVLSacg+DFWCvoiX+JThA/rvw37Sqrku7sEFeVBBBMBnfB6FeZHsyDx85HlKL19x0HtZA==", + "path": "system.text.encoding/4.0.11", + "hashPath": "system.text.encoding.4.0.11.nupkg.sha512" + }, + "System.Text.Encoding.Extensions/4.0.11": { + "type": "package", + "serviceable": true, + "sha512": "sha512-jtbiTDtvfLYgXn8PTfWI+SiBs51rrmO4AAckx4KR6vFK9Wzf6tI8kcRdsYQNwriUeQ1+CtQbM1W4cMbLXnj/OQ==", + "path": "system.text.encoding.extensions/4.0.11", + "hashPath": "system.text.encoding.extensions.4.0.11.nupkg.sha512" + }, + "System.Text.RegularExpressions/4.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-i88YCXpRTjCnoSQZtdlHkAOx4KNNik4hMy83n0+Ftlb7jvV6ZiZWMpnEZHhjBp6hQVh8gWd/iKNPzlPF7iyA2g==", + "path": "system.text.regularexpressions/4.1.0", + "hashPath": "system.text.regularexpressions.4.1.0.nupkg.sha512" + }, + "System.Threading/4.0.11": { + "type": "package", + "serviceable": true, + "sha512": "sha512-N+3xqIcg3VDKyjwwCGaZ9HawG9aC6cSDI+s7ROma310GQo8vilFZa86hqKppwTHleR/G0sfOzhvgnUxWCR/DrQ==", + "path": "system.threading/4.0.11", + "hashPath": "system.threading.4.0.11.nupkg.sha512" + }, + "System.Threading.Tasks/4.0.11": { + "type": "package", + "serviceable": true, + "sha512": "sha512-k1S4Gc6IGwtHGT8188RSeGaX86Qw/wnrgNLshJvsdNUOPP9etMmo8S07c+UlOAx4K/xLuN9ivA1bD0LVurtIxQ==", + "path": "system.threading.tasks/4.0.11", + "hashPath": "system.threading.tasks.4.0.11.nupkg.sha512" + }, + "System.Threading.Tasks.Extensions/4.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-pH4FZDsZQ/WmgJtN4LWYmRdJAEeVkyriSwrv2Teoe5FOU0Yxlb6II6GL8dBPOfRmutHGATduj3ooMt7dJ2+i+w==", + "path": "system.threading.tasks.extensions/4.0.0", + "hashPath": "system.threading.tasks.extensions.4.0.0.nupkg.sha512" + }, + "System.Xml.ReaderWriter/4.0.11": { + "type": "package", + "serviceable": true, + "sha512": "sha512-ZIiLPsf67YZ9zgr31vzrFaYQqxRPX9cVHjtPSnmx4eN6lbS/yEyYNr2vs1doGDEscF0tjCZFsk9yUg1sC9e8tg==", + "path": "system.xml.readerwriter/4.0.11", + "hashPath": "system.xml.readerwriter.4.0.11.nupkg.sha512" + }, + "System.Xml.XDocument/4.0.11": { + "type": "package", + "serviceable": true, + "sha512": "sha512-Mk2mKmPi0nWaoiYeotq1dgeNK1fqWh61+EK+w4Wu8SWuTYLzpUnschb59bJtGywaPq7SmTuPf44wrXRwbIrukg==", + "path": "system.xml.xdocument/4.0.11", + "hashPath": "system.xml.xdocument.4.0.11.nupkg.sha512" + }, + "Legacy.Domain/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "Legacy.Contract/1.0.0.0": { + "type": "reference", + "serviceable": false, + "sha512": "" + } + } +} \ No newline at end of file diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/LegacyPlugin.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/LegacyPlugin.dll new file mode 100644 index 0000000..67a89d9 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/LegacyPlugin.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/LegacyPlugin.pdb b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/LegacyPlugin.pdb new file mode 100644 index 0000000..43a428c Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/LegacyPlugin.pdb differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/Microsoft.CSharp.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/Microsoft.CSharp.dll new file mode 100644 index 0000000..cc29bd3 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/Microsoft.CSharp.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/Microsoft.Extensions.Configuration.Abstractions.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/Microsoft.Extensions.Configuration.Abstractions.dll new file mode 100644 index 0000000..80d73ed Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/Microsoft.Extensions.Configuration.Abstractions.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/Microsoft.Extensions.DependencyInjection.Abstractions.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/Microsoft.Extensions.DependencyInjection.Abstractions.dll new file mode 100644 index 0000000..e557f9d Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/Microsoft.Extensions.DependencyInjection.Abstractions.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/Microsoft.Extensions.DependencyInjection.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/Microsoft.Extensions.DependencyInjection.dll new file mode 100644 index 0000000..4b653bd Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/Microsoft.Extensions.DependencyInjection.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/Microsoft.Extensions.Primitives.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/Microsoft.Extensions.Primitives.dll new file mode 100644 index 0000000..1999bac Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/Microsoft.Extensions.Primitives.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/Newtonsoft.Json.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/Newtonsoft.Json.dll new file mode 100644 index 0000000..5f2336e Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/Newtonsoft.Json.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/Prise.Plugin.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/Prise.Plugin.dll new file mode 100644 index 0000000..d981243 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/Prise.Plugin.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/System.Buffers.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/System.Buffers.dll new file mode 100644 index 0000000..b6d9c77 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/System.Buffers.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/System.Dynamic.Runtime.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/System.Dynamic.Runtime.dll new file mode 100644 index 0000000..c356944 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/System.Dynamic.Runtime.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/System.IO.FileSystem.Primitives.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/System.IO.FileSystem.Primitives.dll new file mode 100644 index 0000000..d5b9bf4 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/System.IO.FileSystem.Primitives.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/System.Linq.Expressions.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/System.Linq.Expressions.dll new file mode 100644 index 0000000..89d0258 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/System.Linq.Expressions.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/System.Linq.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/System.Linq.dll new file mode 100644 index 0000000..6c65169 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/System.Linq.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/System.Memory.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/System.Memory.dll new file mode 100644 index 0000000..078aa55 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/System.Memory.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/System.Numerics.Vectors.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/System.Numerics.Vectors.dll new file mode 100644 index 0000000..a808165 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/System.Numerics.Vectors.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/System.ObjectModel.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/System.ObjectModel.dll new file mode 100644 index 0000000..48b39bc Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/System.ObjectModel.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/System.Reflection.Emit.ILGeneration.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/System.Reflection.Emit.ILGeneration.dll new file mode 100644 index 0000000..1440619 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/System.Reflection.Emit.ILGeneration.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/System.Reflection.Emit.Lightweight.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/System.Reflection.Emit.Lightweight.dll new file mode 100644 index 0000000..cbb550a Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/System.Reflection.Emit.Lightweight.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/System.Reflection.Emit.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/System.Reflection.Emit.dll new file mode 100644 index 0000000..79540d8 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/System.Reflection.Emit.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/System.Reflection.TypeExtensions.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/System.Reflection.TypeExtensions.dll new file mode 100644 index 0000000..e85db4c Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/System.Reflection.TypeExtensions.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/System.Runtime.CompilerServices.Unsafe.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/System.Runtime.CompilerServices.Unsafe.dll new file mode 100644 index 0000000..23a1be2 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/System.Runtime.CompilerServices.Unsafe.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/System.Runtime.Serialization.Primitives.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/System.Runtime.Serialization.Primitives.dll new file mode 100644 index 0000000..7cbc843 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/System.Runtime.Serialization.Primitives.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/System.Text.RegularExpressions.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/System.Text.RegularExpressions.dll new file mode 100644 index 0000000..5008d4e Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/System.Text.RegularExpressions.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/System.Threading.Tasks.Extensions.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/System.Threading.Tasks.Extensions.dll new file mode 100644 index 0000000..42a11c8 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/System.Threading.Tasks.Extensions.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/System.Threading.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/System.Threading.dll new file mode 100644 index 0000000..a87db09 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/System.Threading.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/System.Xml.ReaderWriter.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/System.Xml.ReaderWriter.dll new file mode 100644 index 0000000..28f4e25 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/System.Xml.ReaderWriter.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/System.Xml.XDocument.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/System.Xml.XDocument.dll new file mode 100644 index 0000000..5de6dc2 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.4/System.Xml.XDocument.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/Legacy.Contract.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/Legacy.Contract.dll new file mode 100644 index 0000000..7dd386e Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/Legacy.Contract.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/Legacy.Domain.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/Legacy.Domain.dll new file mode 100644 index 0000000..e3f0512 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/Legacy.Domain.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/Legacy.Domain.pdb b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/Legacy.Domain.pdb new file mode 100644 index 0000000..9064da9 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/Legacy.Domain.pdb differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/LegacyPlugin.deps.json b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/LegacyPlugin.deps.json new file mode 100644 index 0000000..ecddc26 --- /dev/null +++ b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/LegacyPlugin.deps.json @@ -0,0 +1,915 @@ +{ + "runtimeTarget": { + "name": ".NETStandard,Version=v2.0/", + "signature": "" + }, + "compilationOptions": {}, + "targets": { + ".NETStandard,Version=v2.0": {}, + ".NETStandard,Version=v2.0/": { + "LegacyPlugin/1.0.0": { + "dependencies": { + "Legacy.Domain": "1.0.0", + "Microsoft.Extensions.Configuration.Abstractions": "2.1.1", + "NETStandard.Library": "2.0.3", + "Prise.Plugin": "1.5.2", + "Legacy.Contract": "1.0.0.0" + }, + "runtime": { + "LegacyPlugin.dll": {} + } + }, + "Microsoft.CSharp/4.0.1": { + "dependencies": { + "System.Collections": "4.0.11", + "System.Diagnostics.Debug": "4.0.11", + "System.Dynamic.Runtime": "4.0.11", + "System.Globalization": "4.0.11", + "System.Linq": "4.1.0", + "System.Linq.Expressions": "4.1.0", + "System.ObjectModel": "4.0.12", + "System.Reflection": "4.1.0", + "System.Reflection.Extensions": "4.0.1", + "System.Reflection.Primitives": "4.0.1", + "System.Reflection.TypeExtensions": "4.1.0", + "System.Resources.ResourceManager": "4.0.1", + "System.Runtime": "4.1.0", + "System.Runtime.Extensions": "4.1.0", + "System.Runtime.InteropServices": "4.1.0", + "System.Threading": "4.0.11" + }, + "runtime": { + "lib/netstandard1.3/Microsoft.CSharp.dll": { + "assemblyVersion": "4.0.1.0", + "fileVersion": "1.0.24212.1" + } + } + }, + "Microsoft.Extensions.Configuration.Abstractions/2.1.1": { + "dependencies": { + "Microsoft.Extensions.Primitives": "2.1.1" + }, + "runtime": { + "lib/netstandard2.0/Microsoft.Extensions.Configuration.Abstractions.dll": { + "assemblyVersion": "2.1.1.0", + "fileVersion": "2.1.1.18157" + } + } + }, + "Microsoft.Extensions.DependencyInjection/2.1.0": { + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "2.1.0" + }, + "runtime": { + "lib/netstandard2.0/Microsoft.Extensions.DependencyInjection.dll": { + "assemblyVersion": "2.1.0.0", + "fileVersion": "2.1.0.18136" + } + } + }, + "Microsoft.Extensions.DependencyInjection.Abstractions/2.1.0": { + "runtime": { + "lib/netstandard2.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll": { + "assemblyVersion": "2.1.0.0", + "fileVersion": "2.1.0.18136" + } + } + }, + "Microsoft.Extensions.Primitives/2.1.1": { + "dependencies": { + "System.Memory": "4.5.1", + "System.Runtime.CompilerServices.Unsafe": "4.5.1" + }, + "runtime": { + "lib/netstandard2.0/Microsoft.Extensions.Primitives.dll": { + "assemblyVersion": "2.1.1.0", + "fileVersion": "2.1.1.18157" + } + } + }, + "Microsoft.NETCore.Platforms/1.1.0": {}, + "Microsoft.NETCore.Targets/1.0.1": {}, + "NETStandard.Library/2.0.3": { + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0" + } + }, + "Newtonsoft.Json/9.0.1": { + "dependencies": { + "Microsoft.CSharp": "4.0.1", + "System.Collections": "4.0.11", + "System.Diagnostics.Debug": "4.0.11", + "System.Dynamic.Runtime": "4.0.11", + "System.Globalization": "4.0.11", + "System.IO": "4.1.0", + "System.Linq": "4.1.0", + "System.Linq.Expressions": "4.1.0", + "System.ObjectModel": "4.0.12", + "System.Reflection": "4.1.0", + "System.Reflection.Extensions": "4.0.1", + "System.Resources.ResourceManager": "4.0.1", + "System.Runtime": "4.1.0", + "System.Runtime.Extensions": "4.1.0", + "System.Runtime.Serialization.Primitives": "4.1.1", + "System.Text.Encoding": "4.0.11", + "System.Text.Encoding.Extensions": "4.0.11", + "System.Text.RegularExpressions": "4.1.0", + "System.Threading": "4.0.11", + "System.Threading.Tasks": "4.0.11", + "System.Xml.ReaderWriter": "4.0.11", + "System.Xml.XDocument": "4.0.11" + }, + "runtime": { + "lib/netstandard1.0/Newtonsoft.Json.dll": { + "assemblyVersion": "9.0.0.0", + "fileVersion": "9.0.1.19813" + } + } + }, + "Prise.Plugin/1.5.2": { + "dependencies": { + "Microsoft.Extensions.DependencyInjection": "2.1.0" + }, + "runtime": { + "lib/netstandard2.0/Prise.Plugin.dll": { + "assemblyVersion": "1.5.2.0", + "fileVersion": "1.5.2.0" + } + } + }, + "System.Buffers/4.4.0": { + "runtime": { + "lib/netstandard2.0/System.Buffers.dll": { + "assemblyVersion": "4.0.2.0", + "fileVersion": "4.6.25519.3" + } + } + }, + "System.Collections/4.0.11": { + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.0.1", + "System.Runtime": "4.1.0" + } + }, + "System.Diagnostics.Debug/4.0.11": { + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.0.1", + "System.Runtime": "4.1.0" + } + }, + "System.Diagnostics.Tools/4.0.1": { + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.0.1", + "System.Runtime": "4.1.0" + } + }, + "System.Dynamic.Runtime/4.0.11": { + "dependencies": { + "System.Collections": "4.0.11", + "System.Diagnostics.Debug": "4.0.11", + "System.Globalization": "4.0.11", + "System.Linq": "4.1.0", + "System.Linq.Expressions": "4.1.0", + "System.ObjectModel": "4.0.12", + "System.Reflection": "4.1.0", + "System.Reflection.Emit": "4.0.1", + "System.Reflection.Emit.ILGeneration": "4.0.1", + "System.Reflection.Primitives": "4.0.1", + "System.Reflection.TypeExtensions": "4.1.0", + "System.Resources.ResourceManager": "4.0.1", + "System.Runtime": "4.1.0", + "System.Runtime.Extensions": "4.1.0", + "System.Threading": "4.0.11" + }, + "runtime": { + "lib/netstandard1.3/System.Dynamic.Runtime.dll": { + "assemblyVersion": "4.0.11.0", + "fileVersion": "1.0.24212.1" + } + } + }, + "System.Globalization/4.0.11": { + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.0.1", + "System.Runtime": "4.1.0" + } + }, + "System.IO/4.1.0": { + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.0.1", + "System.Runtime": "4.1.0", + "System.Text.Encoding": "4.0.11", + "System.Threading.Tasks": "4.0.11" + } + }, + "System.IO.FileSystem/4.0.1": { + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.0.1", + "System.IO": "4.1.0", + "System.IO.FileSystem.Primitives": "4.0.1", + "System.Runtime": "4.1.0", + "System.Runtime.Handles": "4.0.1", + "System.Text.Encoding": "4.0.11", + "System.Threading.Tasks": "4.0.11" + } + }, + "System.IO.FileSystem.Primitives/4.0.1": { + "dependencies": { + "System.Runtime": "4.1.0" + }, + "runtime": { + "lib/netstandard1.3/System.IO.FileSystem.Primitives.dll": { + "assemblyVersion": "4.0.1.0", + "fileVersion": "1.0.24212.1" + } + } + }, + "System.Linq/4.1.0": { + "dependencies": { + "System.Collections": "4.0.11", + "System.Diagnostics.Debug": "4.0.11", + "System.Resources.ResourceManager": "4.0.1", + "System.Runtime": "4.1.0", + "System.Runtime.Extensions": "4.1.0" + }, + "runtime": { + "lib/netstandard1.6/System.Linq.dll": { + "assemblyVersion": "4.1.0.0", + "fileVersion": "1.0.24212.1" + } + } + }, + "System.Linq.Expressions/4.1.0": { + "dependencies": { + "System.Collections": "4.0.11", + "System.Diagnostics.Debug": "4.0.11", + "System.Globalization": "4.0.11", + "System.IO": "4.1.0", + "System.Linq": "4.1.0", + "System.ObjectModel": "4.0.12", + "System.Reflection": "4.1.0", + "System.Reflection.Emit": "4.0.1", + "System.Reflection.Emit.ILGeneration": "4.0.1", + "System.Reflection.Emit.Lightweight": "4.0.1", + "System.Reflection.Extensions": "4.0.1", + "System.Reflection.Primitives": "4.0.1", + "System.Reflection.TypeExtensions": "4.1.0", + "System.Resources.ResourceManager": "4.0.1", + "System.Runtime": "4.1.0", + "System.Runtime.Extensions": "4.1.0", + "System.Threading": "4.0.11" + }, + "runtime": { + "lib/netstandard1.6/System.Linq.Expressions.dll": { + "assemblyVersion": "4.1.0.0", + "fileVersion": "1.0.24212.1" + } + } + }, + "System.Memory/4.5.1": { + "dependencies": { + "System.Buffers": "4.4.0", + "System.Numerics.Vectors": "4.4.0", + "System.Runtime.CompilerServices.Unsafe": "4.5.1" + }, + "runtime": { + "lib/netstandard2.0/System.Memory.dll": { + "assemblyVersion": "4.0.1.0", + "fileVersion": "4.6.26606.5" + } + } + }, + "System.Numerics.Vectors/4.4.0": { + "runtime": { + "lib/netstandard2.0/System.Numerics.Vectors.dll": { + "assemblyVersion": "4.1.3.0", + "fileVersion": "4.6.25519.3" + } + } + }, + "System.ObjectModel/4.0.12": { + "dependencies": { + "System.Collections": "4.0.11", + "System.Diagnostics.Debug": "4.0.11", + "System.Resources.ResourceManager": "4.0.1", + "System.Runtime": "4.1.0", + "System.Threading": "4.0.11" + }, + "runtime": { + "lib/netstandard1.3/System.ObjectModel.dll": { + "assemblyVersion": "4.0.12.0", + "fileVersion": "1.0.24212.1" + } + } + }, + "System.Reflection/4.1.0": { + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.0.1", + "System.IO": "4.1.0", + "System.Reflection.Primitives": "4.0.1", + "System.Runtime": "4.1.0" + } + }, + "System.Reflection.Emit/4.0.1": { + "dependencies": { + "System.IO": "4.1.0", + "System.Reflection": "4.1.0", + "System.Reflection.Emit.ILGeneration": "4.0.1", + "System.Reflection.Primitives": "4.0.1", + "System.Runtime": "4.1.0" + }, + "runtime": { + "lib/netstandard1.3/System.Reflection.Emit.dll": { + "assemblyVersion": "4.0.1.0", + "fileVersion": "1.0.24212.1" + } + } + }, + "System.Reflection.Emit.ILGeneration/4.0.1": { + "dependencies": { + "System.Reflection": "4.1.0", + "System.Reflection.Primitives": "4.0.1", + "System.Runtime": "4.1.0" + }, + "runtime": { + "lib/netstandard1.3/System.Reflection.Emit.ILGeneration.dll": { + "assemblyVersion": "4.0.1.0", + "fileVersion": "1.0.24212.1" + } + } + }, + "System.Reflection.Emit.Lightweight/4.0.1": { + "dependencies": { + "System.Reflection": "4.1.0", + "System.Reflection.Emit.ILGeneration": "4.0.1", + "System.Reflection.Primitives": "4.0.1", + "System.Runtime": "4.1.0" + }, + "runtime": { + "lib/netstandard1.3/System.Reflection.Emit.Lightweight.dll": { + "assemblyVersion": "4.0.1.0", + "fileVersion": "1.0.24212.1" + } + } + }, + "System.Reflection.Extensions/4.0.1": { + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.0.1", + "System.Reflection": "4.1.0", + "System.Runtime": "4.1.0" + } + }, + "System.Reflection.Primitives/4.0.1": { + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.0.1", + "System.Runtime": "4.1.0" + } + }, + "System.Reflection.TypeExtensions/4.1.0": { + "dependencies": { + "System.Reflection": "4.1.0", + "System.Runtime": "4.1.0" + }, + "runtime": { + "lib/netstandard1.5/System.Reflection.TypeExtensions.dll": { + "assemblyVersion": "4.1.0.0", + "fileVersion": "1.0.24212.1" + } + } + }, + "System.Resources.ResourceManager/4.0.1": { + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.0.1", + "System.Globalization": "4.0.11", + "System.Reflection": "4.1.0", + "System.Runtime": "4.1.0" + } + }, + "System.Runtime/4.1.0": { + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.0.1" + } + }, + "System.Runtime.CompilerServices.Unsafe/4.5.1": { + "runtime": { + "lib/netstandard2.0/System.Runtime.CompilerServices.Unsafe.dll": { + "assemblyVersion": "4.0.4.0", + "fileVersion": "0.0.0.0" + } + } + }, + "System.Runtime.Extensions/4.1.0": { + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.0.1", + "System.Runtime": "4.1.0" + } + }, + "System.Runtime.Handles/4.0.1": { + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.0.1", + "System.Runtime": "4.1.0" + } + }, + "System.Runtime.InteropServices/4.1.0": { + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.0.1", + "System.Reflection": "4.1.0", + "System.Reflection.Primitives": "4.0.1", + "System.Runtime": "4.1.0", + "System.Runtime.Handles": "4.0.1" + } + }, + "System.Runtime.Serialization.Primitives/4.1.1": { + "dependencies": { + "System.Resources.ResourceManager": "4.0.1", + "System.Runtime": "4.1.0" + }, + "runtime": { + "lib/netstandard1.3/System.Runtime.Serialization.Primitives.dll": { + "assemblyVersion": "4.1.1.0", + "fileVersion": "1.0.24212.1" + } + } + }, + "System.Text.Encoding/4.0.11": { + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.0.1", + "System.Runtime": "4.1.0" + } + }, + "System.Text.Encoding.Extensions/4.0.11": { + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.0.1", + "System.Runtime": "4.1.0", + "System.Text.Encoding": "4.0.11" + } + }, + "System.Text.RegularExpressions/4.1.0": { + "dependencies": { + "System.Collections": "4.0.11", + "System.Globalization": "4.0.11", + "System.Resources.ResourceManager": "4.0.1", + "System.Runtime": "4.1.0", + "System.Runtime.Extensions": "4.1.0", + "System.Threading": "4.0.11" + }, + "runtime": { + "lib/netstandard1.6/System.Text.RegularExpressions.dll": { + "assemblyVersion": "4.1.0.0", + "fileVersion": "1.0.24212.1" + } + } + }, + "System.Threading/4.0.11": { + "dependencies": { + "System.Runtime": "4.1.0", + "System.Threading.Tasks": "4.0.11" + }, + "runtime": { + "lib/netstandard1.3/System.Threading.dll": { + "assemblyVersion": "4.0.11.0", + "fileVersion": "1.0.24212.1" + } + } + }, + "System.Threading.Tasks/4.0.11": { + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.0.1", + "System.Runtime": "4.1.0" + } + }, + "System.Threading.Tasks.Extensions/4.0.0": { + "dependencies": { + "System.Collections": "4.0.11", + "System.Runtime": "4.1.0", + "System.Threading.Tasks": "4.0.11" + }, + "runtime": { + "lib/netstandard1.0/System.Threading.Tasks.Extensions.dll": { + "assemblyVersion": "4.0.0.0", + "fileVersion": "1.0.24212.1" + } + } + }, + "System.Xml.ReaderWriter/4.0.11": { + "dependencies": { + "System.Collections": "4.0.11", + "System.Diagnostics.Debug": "4.0.11", + "System.Globalization": "4.0.11", + "System.IO": "4.1.0", + "System.IO.FileSystem": "4.0.1", + "System.IO.FileSystem.Primitives": "4.0.1", + "System.Resources.ResourceManager": "4.0.1", + "System.Runtime": "4.1.0", + "System.Runtime.Extensions": "4.1.0", + "System.Runtime.InteropServices": "4.1.0", + "System.Text.Encoding": "4.0.11", + "System.Text.Encoding.Extensions": "4.0.11", + "System.Text.RegularExpressions": "4.1.0", + "System.Threading.Tasks": "4.0.11", + "System.Threading.Tasks.Extensions": "4.0.0" + }, + "runtime": { + "lib/netstandard1.3/System.Xml.ReaderWriter.dll": { + "assemblyVersion": "4.0.11.0", + "fileVersion": "1.0.24212.1" + } + } + }, + "System.Xml.XDocument/4.0.11": { + "dependencies": { + "System.Collections": "4.0.11", + "System.Diagnostics.Debug": "4.0.11", + "System.Diagnostics.Tools": "4.0.1", + "System.Globalization": "4.0.11", + "System.IO": "4.1.0", + "System.Reflection": "4.1.0", + "System.Resources.ResourceManager": "4.0.1", + "System.Runtime": "4.1.0", + "System.Runtime.Extensions": "4.1.0", + "System.Text.Encoding": "4.0.11", + "System.Threading": "4.0.11", + "System.Xml.ReaderWriter": "4.0.11" + }, + "runtime": { + "lib/netstandard1.3/System.Xml.XDocument.dll": { + "assemblyVersion": "4.0.11.0", + "fileVersion": "1.0.24212.1" + } + } + }, + "Legacy.Domain/1.0.0": { + "dependencies": { + "Newtonsoft.Json": "9.0.1" + }, + "runtime": { + "Legacy.Domain.dll": {} + } + }, + "Legacy.Contract/1.0.0.0": { + "runtime": { + "Legacy.Contract.dll": { + "assemblyVersion": "1.0.0.0", + "fileVersion": "1.0.0.0" + } + } + } + } + }, + "libraries": { + "LegacyPlugin/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "Microsoft.CSharp/4.0.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-17h8b5mXa87XYKrrVqdgZ38JefSUqLChUQpXgSnpzsM0nDOhE40FTeNWOJ/YmySGV6tG6T8+hjz6vxbknHJr6A==", + "path": "microsoft.csharp/4.0.1", + "hashPath": "microsoft.csharp.4.0.1.nupkg.sha512" + }, + "Microsoft.Extensions.Configuration.Abstractions/2.1.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-VfuZJNa0WUshZ/+8BFZAhwFKiKuu/qOUCFntfdLpHj7vcRnsGHqd3G2Hse78DM+pgozczGM63lGPRLmy+uhUOA==", + "path": "microsoft.extensions.configuration.abstractions/2.1.1", + "hashPath": "microsoft.extensions.configuration.abstractions.2.1.1.nupkg.sha512" + }, + "Microsoft.Extensions.DependencyInjection/2.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-gqQviLfuA31PheEGi+XJoZc1bc9H9RsPa9Gq9XuDct7XGWSR9eVXjK5Sg7CSUPhTFHSuxUFY12wcTYLZ4zM1hg==", + "path": "microsoft.extensions.dependencyinjection/2.1.0", + "hashPath": "microsoft.extensions.dependencyinjection.2.1.0.nupkg.sha512" + }, + "Microsoft.Extensions.DependencyInjection.Abstractions/2.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-8/CtASu80UIoyG+r8FstrmZW5GLtXxzoYpjj3jV0FKZCL5CiFgSH3pAmqut/dC68mu7N1bU6v0UtKKL3gCUQGQ==", + "path": "microsoft.extensions.dependencyinjection.abstractions/2.1.0", + "hashPath": "microsoft.extensions.dependencyinjection.abstractions.2.1.0.nupkg.sha512" + }, + "Microsoft.Extensions.Primitives/2.1.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-scJ1GZNIxMmjpENh0UZ8XCQ6vzr/LzeF9WvEA51Ix2OQGAs9WPgPu8ABVUdvpKPLuor/t05gm6menJK3PwqOXg==", + "path": "microsoft.extensions.primitives/2.1.1", + "hashPath": "microsoft.extensions.primitives.2.1.1.nupkg.sha512" + }, + "Microsoft.NETCore.Platforms/1.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-kz0PEW2lhqygehI/d6XsPCQzD7ff7gUJaVGPVETX611eadGsA3A877GdSlU0LRVMCTH/+P3o2iDTak+S08V2+A==", + "path": "microsoft.netcore.platforms/1.1.0", + "hashPath": "microsoft.netcore.platforms.1.1.0.nupkg.sha512" + }, + "Microsoft.NETCore.Targets/1.0.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-rkn+fKobF/cbWfnnfBOQHKVKIOpxMZBvlSHkqDWgBpwGDcLRduvs3D9OLGeV6GWGvVwNlVi2CBbTjuPmtHvyNw==", + "path": "microsoft.netcore.targets/1.0.1", + "hashPath": "microsoft.netcore.targets.1.0.1.nupkg.sha512" + }, + "NETStandard.Library/2.0.3": { + "type": "package", + "serviceable": true, + "sha512": "sha512-st47PosZSHrjECdjeIzZQbzivYBJFv6P2nv4cj2ypdI204DO+vZ7l5raGMiX4eXMJ53RfOIg+/s4DHVZ54Nu2A==", + "path": "netstandard.library/2.0.3", + "hashPath": "netstandard.library.2.0.3.nupkg.sha512" + }, + "Newtonsoft.Json/9.0.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-U82mHQSKaIk+lpSVCbWYKNavmNH1i5xrExDEquU1i6I5pV6UMOqRnJRSlKO3cMPfcpp0RgDY+8jUXHdQ4IfXvw==", + "path": "newtonsoft.json/9.0.1", + "hashPath": "newtonsoft.json.9.0.1.nupkg.sha512" + }, + "Prise.Plugin/1.5.2": { + "type": "package", + "serviceable": true, + "sha512": "sha512-yhqAVanwAJRYH0EQcHoYCAjR5IB+K5XQ9ED+xDXHLGKIPGKfcfZgUsys7X7PRdI27eku8VqtAe0qPwB8qkwnvw==", + "path": "prise.plugin/1.5.2", + "hashPath": "prise.plugin.1.5.2.nupkg.sha512" + }, + "System.Buffers/4.4.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-AwarXzzoDwX6BgrhjoJsk6tUezZEozOT5Y9QKF94Gl4JK91I4PIIBkBco9068Y9/Dra8Dkbie99kXB8+1BaYKw==", + "path": "system.buffers/4.4.0", + "hashPath": "system.buffers.4.4.0.nupkg.sha512" + }, + "System.Collections/4.0.11": { + "type": "package", + "serviceable": true, + "sha512": "sha512-YUJGz6eFKqS0V//mLt25vFGrrCvOnsXjlvFQs+KimpwNxug9x0Pzy4PlFMU3Q2IzqAa9G2L4LsK3+9vCBK7oTg==", + "path": "system.collections/4.0.11", + "hashPath": "system.collections.4.0.11.nupkg.sha512" + }, + "System.Diagnostics.Debug/4.0.11": { + "type": "package", + "serviceable": true, + "sha512": "sha512-w5U95fVKHY4G8ASs/K5iK3J5LY+/dLFd4vKejsnI/ZhBsWS9hQakfx3Zr7lRWKg4tAw9r4iktyvsTagWkqYCiw==", + "path": "system.diagnostics.debug/4.0.11", + "hashPath": "system.diagnostics.debug.4.0.11.nupkg.sha512" + }, + "System.Diagnostics.Tools/4.0.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-xBfJ8pnd4C17dWaC9FM6aShzbJcRNMChUMD42I6772KGGrqaFdumwhn9OdM68erj1ueNo3xdQ1EwiFjK5k8p0g==", + "path": "system.diagnostics.tools/4.0.1", + "hashPath": "system.diagnostics.tools.4.0.1.nupkg.sha512" + }, + "System.Dynamic.Runtime/4.0.11": { + "type": "package", + "serviceable": true, + "sha512": "sha512-db34f6LHYM0U0JpE+sOmjar27BnqTVkbLJhgfwMpTdgTigG/Hna3m2MYVwnFzGGKnEJk2UXFuoVTr8WUbU91/A==", + "path": "system.dynamic.runtime/4.0.11", + "hashPath": "system.dynamic.runtime.4.0.11.nupkg.sha512" + }, + "System.Globalization/4.0.11": { + "type": "package", + "serviceable": true, + "sha512": "sha512-B95h0YLEL2oSnwF/XjqSWKnwKOy/01VWkNlsCeMTFJLLabflpGV26nK164eRs5GiaRSBGpOxQ3pKoSnnyZN5pg==", + "path": "system.globalization/4.0.11", + "hashPath": "system.globalization.4.0.11.nupkg.sha512" + }, + "System.IO/4.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-3KlTJceQc3gnGIaHZ7UBZO26SHL1SHE4ddrmiwumFnId+CEHP+O8r386tZKaE6zlk5/mF8vifMBzHj9SaXN+mQ==", + "path": "system.io/4.1.0", + "hashPath": "system.io.4.1.0.nupkg.sha512" + }, + "System.IO.FileSystem/4.0.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-IBErlVq5jOggAD69bg1t0pJcHaDbJbWNUZTPI96fkYWzwYbN6D9wRHMULLDd9dHsl7C2YsxXL31LMfPI1SWt8w==", + "path": "system.io.filesystem/4.0.1", + "hashPath": "system.io.filesystem.4.0.1.nupkg.sha512" + }, + "System.IO.FileSystem.Primitives/4.0.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-kWkKD203JJKxJeE74p8aF8y4Qc9r9WQx4C0cHzHPrY3fv/L/IhWnyCHaFJ3H1QPOH6A93whlQ2vG5nHlBDvzWQ==", + "path": "system.io.filesystem.primitives/4.0.1", + "hashPath": "system.io.filesystem.primitives.4.0.1.nupkg.sha512" + }, + "System.Linq/4.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-bQ0iYFOQI0nuTnt+NQADns6ucV4DUvMdwN6CbkB1yj8i7arTGiTN5eok1kQwdnnNWSDZfIUySQY+J3d5KjWn0g==", + "path": "system.linq/4.1.0", + "hashPath": "system.linq.4.1.0.nupkg.sha512" + }, + "System.Linq.Expressions/4.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-I+y02iqkgmCAyfbqOmSDOgqdZQ5tTj80Akm5BPSS8EeB0VGWdy6X1KCoYe8Pk6pwDoAKZUOdLVxnTJcExiv5zw==", + "path": "system.linq.expressions/4.1.0", + "hashPath": "system.linq.expressions.4.1.0.nupkg.sha512" + }, + "System.Memory/4.5.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-sDJYJpGtTgx+23Ayu5euxG5mAXWdkDb4+b0rD0Cab0M1oQS9H0HXGPriKcqpXuiJDTV7fTp/d+fMDJmnr6sNvA==", + "path": "system.memory/4.5.1", + "hashPath": "system.memory.4.5.1.nupkg.sha512" + }, + "System.Numerics.Vectors/4.4.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-UiLzLW+Lw6HLed1Hcg+8jSRttrbuXv7DANVj0DkL9g6EnnzbL75EB7EWsw5uRbhxd/4YdG8li5XizGWepmG3PQ==", + "path": "system.numerics.vectors/4.4.0", + "hashPath": "system.numerics.vectors.4.4.0.nupkg.sha512" + }, + "System.ObjectModel/4.0.12": { + "type": "package", + "serviceable": true, + "sha512": "sha512-tAgJM1xt3ytyMoW4qn4wIqgJYm7L7TShRZG4+Q4Qsi2PCcj96pXN7nRywS9KkB3p/xDUjc2HSwP9SROyPYDYKQ==", + "path": "system.objectmodel/4.0.12", + "hashPath": "system.objectmodel.4.0.12.nupkg.sha512" + }, + "System.Reflection/4.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-JCKANJ0TI7kzoQzuwB/OoJANy1Lg338B6+JVacPl4TpUwi3cReg3nMLplMq2uqYfHFQpKIlHAUVAJlImZz/4ng==", + "path": "system.reflection/4.1.0", + "hashPath": "system.reflection.4.1.0.nupkg.sha512" + }, + "System.Reflection.Emit/4.0.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-P2wqAj72fFjpP6wb9nSfDqNBMab+2ovzSDzUZK7MVIm54tBJEPr9jWfSjjoTpPwj1LeKcmX3vr0ttyjSSFM47g==", + "path": "system.reflection.emit/4.0.1", + "hashPath": "system.reflection.emit.4.0.1.nupkg.sha512" + }, + "System.Reflection.Emit.ILGeneration/4.0.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-Ov6dU8Bu15Bc7zuqttgHF12J5lwSWyTf1S+FJouUXVMSqImLZzYaQ+vRr1rQ0OZ0HqsrwWl4dsKHELckQkVpgA==", + "path": "system.reflection.emit.ilgeneration/4.0.1", + "hashPath": "system.reflection.emit.ilgeneration.4.0.1.nupkg.sha512" + }, + "System.Reflection.Emit.Lightweight/4.0.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-sSzHHXueZ5Uh0OLpUQprhr+ZYJrLPA2Cmr4gn0wj9+FftNKXx8RIMKvO9qnjk2ebPYUjZ+F2ulGdPOsvj+MEjA==", + "path": "system.reflection.emit.lightweight/4.0.1", + "hashPath": "system.reflection.emit.lightweight.4.0.1.nupkg.sha512" + }, + "System.Reflection.Extensions/4.0.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-GYrtRsZcMuHF3sbmRHfMYpvxZoIN2bQGrYGerUiWLEkqdEUQZhH3TRSaC/oI4wO0II1RKBPlpIa1TOMxIcOOzQ==", + "path": "system.reflection.extensions/4.0.1", + "hashPath": "system.reflection.extensions.4.0.1.nupkg.sha512" + }, + "System.Reflection.Primitives/4.0.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-4inTox4wTBaDhB7V3mPvp9XlCbeGYWVEM9/fXALd52vNEAVisc1BoVWQPuUuD0Ga//dNbA/WeMy9u9mzLxGTHQ==", + "path": "system.reflection.primitives/4.0.1", + "hashPath": "system.reflection.primitives.4.0.1.nupkg.sha512" + }, + "System.Reflection.TypeExtensions/4.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-tsQ/ptQ3H5FYfON8lL4MxRk/8kFyE0A+tGPXmVP967cT/gzLHYxIejIYSxp4JmIeFHVP78g/F2FE1mUUTbDtrg==", + "path": "system.reflection.typeextensions/4.1.0", + "hashPath": "system.reflection.typeextensions.4.1.0.nupkg.sha512" + }, + "System.Resources.ResourceManager/4.0.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-TxwVeUNoTgUOdQ09gfTjvW411MF+w9MBYL7AtNVc+HtBCFlutPLhUCdZjNkjbhj3bNQWMdHboF0KIWEOjJssbA==", + "path": "system.resources.resourcemanager/4.0.1", + "hashPath": "system.resources.resourcemanager.4.0.1.nupkg.sha512" + }, + "System.Runtime/4.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-v6c/4Yaa9uWsq+JMhnOFewrYkgdNHNG2eMKuNqRn8P733rNXeRCGvV5FkkjBXn2dbVkPXOsO0xjsEeM1q2zC0g==", + "path": "system.runtime/4.1.0", + "hashPath": "system.runtime.4.1.0.nupkg.sha512" + }, + "System.Runtime.CompilerServices.Unsafe/4.5.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-Zh8t8oqolRaFa9vmOZfdQm/qKejdqz0J9kr7o2Fu0vPeoH3BL1EOXipKWwkWtLT1JPzjByrF19fGuFlNbmPpiw==", + "path": "system.runtime.compilerservices.unsafe/4.5.1", + "hashPath": "system.runtime.compilerservices.unsafe.4.5.1.nupkg.sha512" + }, + "System.Runtime.Extensions/4.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-CUOHjTT/vgP0qGW22U4/hDlOqXmcPq5YicBaXdUR2UiUoLwBT+olO6we4DVbq57jeX5uXH2uerVZhf0qGj+sVQ==", + "path": "system.runtime.extensions/4.1.0", + "hashPath": "system.runtime.extensions.4.1.0.nupkg.sha512" + }, + "System.Runtime.Handles/4.0.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-nCJvEKguXEvk2ymk1gqj625vVnlK3/xdGzx0vOKicQkoquaTBJTP13AIYkocSUwHCLNBwUbXTqTWGDxBTWpt7g==", + "path": "system.runtime.handles/4.0.1", + "hashPath": "system.runtime.handles.4.0.1.nupkg.sha512" + }, + "System.Runtime.InteropServices/4.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-16eu3kjHS633yYdkjwShDHZLRNMKVi/s0bY8ODiqJ2RfMhDMAwxZaUaWVnZ2P71kr/or+X9o/xFWtNqz8ivieQ==", + "path": "system.runtime.interopservices/4.1.0", + "hashPath": "system.runtime.interopservices.4.1.0.nupkg.sha512" + }, + "System.Runtime.Serialization.Primitives/4.1.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-HZ6Du5QrTG8MNJbf4e4qMO3JRAkIboGT5Fk804uZtg3Gq516S7hAqTm2UZKUHa7/6HUGdVy3AqMQKbns06G/cg==", + "path": "system.runtime.serialization.primitives/4.1.1", + "hashPath": "system.runtime.serialization.primitives.4.1.1.nupkg.sha512" + }, + "System.Text.Encoding/4.0.11": { + "type": "package", + "serviceable": true, + "sha512": "sha512-U3gGeMlDZXxCEiY4DwVLSacg+DFWCvoiX+JThA/rvw37Sqrku7sEFeVBBBMBnfB6FeZHsyDx85HlKL19x0HtZA==", + "path": "system.text.encoding/4.0.11", + "hashPath": "system.text.encoding.4.0.11.nupkg.sha512" + }, + "System.Text.Encoding.Extensions/4.0.11": { + "type": "package", + "serviceable": true, + "sha512": "sha512-jtbiTDtvfLYgXn8PTfWI+SiBs51rrmO4AAckx4KR6vFK9Wzf6tI8kcRdsYQNwriUeQ1+CtQbM1W4cMbLXnj/OQ==", + "path": "system.text.encoding.extensions/4.0.11", + "hashPath": "system.text.encoding.extensions.4.0.11.nupkg.sha512" + }, + "System.Text.RegularExpressions/4.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-i88YCXpRTjCnoSQZtdlHkAOx4KNNik4hMy83n0+Ftlb7jvV6ZiZWMpnEZHhjBp6hQVh8gWd/iKNPzlPF7iyA2g==", + "path": "system.text.regularexpressions/4.1.0", + "hashPath": "system.text.regularexpressions.4.1.0.nupkg.sha512" + }, + "System.Threading/4.0.11": { + "type": "package", + "serviceable": true, + "sha512": "sha512-N+3xqIcg3VDKyjwwCGaZ9HawG9aC6cSDI+s7ROma310GQo8vilFZa86hqKppwTHleR/G0sfOzhvgnUxWCR/DrQ==", + "path": "system.threading/4.0.11", + "hashPath": "system.threading.4.0.11.nupkg.sha512" + }, + "System.Threading.Tasks/4.0.11": { + "type": "package", + "serviceable": true, + "sha512": "sha512-k1S4Gc6IGwtHGT8188RSeGaX86Qw/wnrgNLshJvsdNUOPP9etMmo8S07c+UlOAx4K/xLuN9ivA1bD0LVurtIxQ==", + "path": "system.threading.tasks/4.0.11", + "hashPath": "system.threading.tasks.4.0.11.nupkg.sha512" + }, + "System.Threading.Tasks.Extensions/4.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-pH4FZDsZQ/WmgJtN4LWYmRdJAEeVkyriSwrv2Teoe5FOU0Yxlb6II6GL8dBPOfRmutHGATduj3ooMt7dJ2+i+w==", + "path": "system.threading.tasks.extensions/4.0.0", + "hashPath": "system.threading.tasks.extensions.4.0.0.nupkg.sha512" + }, + "System.Xml.ReaderWriter/4.0.11": { + "type": "package", + "serviceable": true, + "sha512": "sha512-ZIiLPsf67YZ9zgr31vzrFaYQqxRPX9cVHjtPSnmx4eN6lbS/yEyYNr2vs1doGDEscF0tjCZFsk9yUg1sC9e8tg==", + "path": "system.xml.readerwriter/4.0.11", + "hashPath": "system.xml.readerwriter.4.0.11.nupkg.sha512" + }, + "System.Xml.XDocument/4.0.11": { + "type": "package", + "serviceable": true, + "sha512": "sha512-Mk2mKmPi0nWaoiYeotq1dgeNK1fqWh61+EK+w4Wu8SWuTYLzpUnschb59bJtGywaPq7SmTuPf44wrXRwbIrukg==", + "path": "system.xml.xdocument/4.0.11", + "hashPath": "system.xml.xdocument.4.0.11.nupkg.sha512" + }, + "Legacy.Domain/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "Legacy.Contract/1.0.0.0": { + "type": "reference", + "serviceable": false, + "sha512": "" + } + } +} \ No newline at end of file diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/LegacyPlugin.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/LegacyPlugin.dll new file mode 100644 index 0000000..25d4d50 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/LegacyPlugin.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/LegacyPlugin.pdb b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/LegacyPlugin.pdb new file mode 100644 index 0000000..6349400 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/LegacyPlugin.pdb differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/Microsoft.CSharp.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/Microsoft.CSharp.dll new file mode 100644 index 0000000..cc29bd3 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/Microsoft.CSharp.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/Microsoft.Extensions.Configuration.Abstractions.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/Microsoft.Extensions.Configuration.Abstractions.dll new file mode 100644 index 0000000..80d73ed Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/Microsoft.Extensions.Configuration.Abstractions.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/Microsoft.Extensions.DependencyInjection.Abstractions.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/Microsoft.Extensions.DependencyInjection.Abstractions.dll new file mode 100644 index 0000000..e557f9d Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/Microsoft.Extensions.DependencyInjection.Abstractions.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/Microsoft.Extensions.DependencyInjection.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/Microsoft.Extensions.DependencyInjection.dll new file mode 100644 index 0000000..4b653bd Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/Microsoft.Extensions.DependencyInjection.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/Microsoft.Extensions.Primitives.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/Microsoft.Extensions.Primitives.dll new file mode 100644 index 0000000..1999bac Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/Microsoft.Extensions.Primitives.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/Newtonsoft.Json.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/Newtonsoft.Json.dll new file mode 100644 index 0000000..5f2336e Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/Newtonsoft.Json.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/Prise.Plugin.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/Prise.Plugin.dll new file mode 100644 index 0000000..38f3065 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/Prise.Plugin.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/System.Buffers.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/System.Buffers.dll new file mode 100644 index 0000000..b6d9c77 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/System.Buffers.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/System.Dynamic.Runtime.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/System.Dynamic.Runtime.dll new file mode 100644 index 0000000..c356944 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/System.Dynamic.Runtime.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/System.IO.FileSystem.Primitives.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/System.IO.FileSystem.Primitives.dll new file mode 100644 index 0000000..d5b9bf4 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/System.IO.FileSystem.Primitives.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/System.Linq.Expressions.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/System.Linq.Expressions.dll new file mode 100644 index 0000000..89d0258 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/System.Linq.Expressions.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/System.Linq.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/System.Linq.dll new file mode 100644 index 0000000..6c65169 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/System.Linq.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/System.Memory.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/System.Memory.dll new file mode 100644 index 0000000..078aa55 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/System.Memory.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/System.Numerics.Vectors.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/System.Numerics.Vectors.dll new file mode 100644 index 0000000..a808165 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/System.Numerics.Vectors.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/System.ObjectModel.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/System.ObjectModel.dll new file mode 100644 index 0000000..48b39bc Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/System.ObjectModel.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/System.Reflection.Emit.ILGeneration.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/System.Reflection.Emit.ILGeneration.dll new file mode 100644 index 0000000..1440619 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/System.Reflection.Emit.ILGeneration.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/System.Reflection.Emit.Lightweight.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/System.Reflection.Emit.Lightweight.dll new file mode 100644 index 0000000..cbb550a Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/System.Reflection.Emit.Lightweight.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/System.Reflection.Emit.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/System.Reflection.Emit.dll new file mode 100644 index 0000000..79540d8 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/System.Reflection.Emit.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/System.Reflection.TypeExtensions.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/System.Reflection.TypeExtensions.dll new file mode 100644 index 0000000..e85db4c Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/System.Reflection.TypeExtensions.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/System.Runtime.CompilerServices.Unsafe.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/System.Runtime.CompilerServices.Unsafe.dll new file mode 100644 index 0000000..23a1be2 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/System.Runtime.CompilerServices.Unsafe.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/System.Runtime.Serialization.Primitives.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/System.Runtime.Serialization.Primitives.dll new file mode 100644 index 0000000..7cbc843 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/System.Runtime.Serialization.Primitives.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/System.Text.RegularExpressions.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/System.Text.RegularExpressions.dll new file mode 100644 index 0000000..5008d4e Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/System.Text.RegularExpressions.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/System.Threading.Tasks.Extensions.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/System.Threading.Tasks.Extensions.dll new file mode 100644 index 0000000..42a11c8 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/System.Threading.Tasks.Extensions.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/System.Threading.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/System.Threading.dll new file mode 100644 index 0000000..a87db09 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/System.Threading.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/System.Xml.ReaderWriter.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/System.Xml.ReaderWriter.dll new file mode 100644 index 0000000..28f4e25 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/System.Xml.ReaderWriter.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/System.Xml.XDocument.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/System.Xml.XDocument.dll new file mode 100644 index 0000000..5de6dc2 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/LegacyPlugin1.5/System.Xml.XDocument.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginA/Microsoft.Extensions.DependencyInjection.Abstractions.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginA/Microsoft.Extensions.DependencyInjection.Abstractions.dll new file mode 100644 index 0000000..e557f9d Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginA/Microsoft.Extensions.DependencyInjection.Abstractions.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginA/Microsoft.Extensions.DependencyInjection.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginA/Microsoft.Extensions.DependencyInjection.dll new file mode 100644 index 0000000..4b653bd Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginA/Microsoft.Extensions.DependencyInjection.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginA/PluginA.deps.json b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginA/PluginA.deps.json new file mode 100644 index 0000000..2ddb59a --- /dev/null +++ b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginA/PluginA.deps.json @@ -0,0 +1,105 @@ +{ + "runtimeTarget": { + "name": ".NETStandard,Version=v2.0/", + "signature": "" + }, + "compilationOptions": {}, + "targets": { + ".NETStandard,Version=v2.0": {}, + ".NETStandard,Version=v2.0/": { + "PluginA/1.0.0": { + "dependencies": { + "NETStandard.Library": "2.0.3", + "Prise.IntegrationTestsContract": "1.0.0", + "Prise.Plugin": "1.0.0" + }, + "runtime": { + "PluginA.dll": {} + } + }, + "Microsoft.Extensions.DependencyInjection/2.1.0": { + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "2.1.0" + }, + "runtime": { + "lib/netstandard2.0/Microsoft.Extensions.DependencyInjection.dll": { + "assemblyVersion": "2.1.0.0", + "fileVersion": "2.1.0.18136" + } + } + }, + "Microsoft.Extensions.DependencyInjection.Abstractions/2.1.0": { + "runtime": { + "lib/netstandard2.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll": { + "assemblyVersion": "2.1.0.0", + "fileVersion": "2.1.0.18136" + } + } + }, + "Microsoft.NETCore.Platforms/1.1.0": {}, + "NETStandard.Library/2.0.3": { + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0" + } + }, + "Prise.IntegrationTestsContract/1.0.0": { + "runtime": { + "Prise.IntegrationTestsContract.dll": {} + } + }, + "Prise.Plugin/1.0.0": { + "dependencies": { + "Microsoft.Extensions.DependencyInjection": "2.1.0" + }, + "runtime": { + "Prise.Plugin.dll": {} + } + } + } + }, + "libraries": { + "PluginA/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "Microsoft.Extensions.DependencyInjection/2.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-gqQviLfuA31PheEGi+XJoZc1bc9H9RsPa9Gq9XuDct7XGWSR9eVXjK5Sg7CSUPhTFHSuxUFY12wcTYLZ4zM1hg==", + "path": "microsoft.extensions.dependencyinjection/2.1.0", + "hashPath": "microsoft.extensions.dependencyinjection.2.1.0.nupkg.sha512" + }, + "Microsoft.Extensions.DependencyInjection.Abstractions/2.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-8/CtASu80UIoyG+r8FstrmZW5GLtXxzoYpjj3jV0FKZCL5CiFgSH3pAmqut/dC68mu7N1bU6v0UtKKL3gCUQGQ==", + "path": "microsoft.extensions.dependencyinjection.abstractions/2.1.0", + "hashPath": "microsoft.extensions.dependencyinjection.abstractions.2.1.0.nupkg.sha512" + }, + "Microsoft.NETCore.Platforms/1.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-kz0PEW2lhqygehI/d6XsPCQzD7ff7gUJaVGPVETX611eadGsA3A877GdSlU0LRVMCTH/+P3o2iDTak+S08V2+A==", + "path": "microsoft.netcore.platforms/1.1.0", + "hashPath": "microsoft.netcore.platforms.1.1.0.nupkg.sha512" + }, + "NETStandard.Library/2.0.3": { + "type": "package", + "serviceable": true, + "sha512": "sha512-st47PosZSHrjECdjeIzZQbzivYBJFv6P2nv4cj2ypdI204DO+vZ7l5raGMiX4eXMJ53RfOIg+/s4DHVZ54Nu2A==", + "path": "netstandard.library/2.0.3", + "hashPath": "netstandard.library.2.0.3.nupkg.sha512" + }, + "Prise.IntegrationTestsContract/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "Prise.Plugin/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + } + } +} \ No newline at end of file diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginA/PluginA.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginA/PluginA.dll new file mode 100644 index 0000000..93889ce Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginA/PluginA.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginA/PluginA.pdb b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginA/PluginA.pdb new file mode 100644 index 0000000..604108a Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginA/PluginA.pdb differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginA/Prise.IntegrationTestsContract.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginA/Prise.IntegrationTestsContract.dll new file mode 100644 index 0000000..8eb98f9 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginA/Prise.IntegrationTestsContract.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginA/Prise.IntegrationTestsContract.pdb b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginA/Prise.IntegrationTestsContract.pdb new file mode 100644 index 0000000..b42bf62 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginA/Prise.IntegrationTestsContract.pdb differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginA/Prise.Plugin.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginA/Prise.Plugin.dll new file mode 100644 index 0000000..12c6767 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginA/Prise.Plugin.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginA/Prise.Plugin.pdb b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginA/Prise.Plugin.pdb new file mode 100644 index 0000000..c153ddc Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginA/Prise.Plugin.pdb differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginB/Microsoft.Extensions.DependencyInjection.Abstractions.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginB/Microsoft.Extensions.DependencyInjection.Abstractions.dll new file mode 100644 index 0000000..e557f9d Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginB/Microsoft.Extensions.DependencyInjection.Abstractions.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginB/Microsoft.Extensions.DependencyInjection.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginB/Microsoft.Extensions.DependencyInjection.dll new file mode 100644 index 0000000..4b653bd Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginB/Microsoft.Extensions.DependencyInjection.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginB/PluginB.deps.json b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginB/PluginB.deps.json new file mode 100644 index 0000000..9c17343 --- /dev/null +++ b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginB/PluginB.deps.json @@ -0,0 +1,105 @@ +{ + "runtimeTarget": { + "name": ".NETStandard,Version=v2.0/", + "signature": "" + }, + "compilationOptions": {}, + "targets": { + ".NETStandard,Version=v2.0": {}, + ".NETStandard,Version=v2.0/": { + "PluginB/1.0.0": { + "dependencies": { + "NETStandard.Library": "2.0.3", + "Prise.IntegrationTestsContract": "1.0.0", + "Prise.Plugin": "1.0.0" + }, + "runtime": { + "PluginB.dll": {} + } + }, + "Microsoft.Extensions.DependencyInjection/2.1.0": { + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "2.1.0" + }, + "runtime": { + "lib/netstandard2.0/Microsoft.Extensions.DependencyInjection.dll": { + "assemblyVersion": "2.1.0.0", + "fileVersion": "2.1.0.18136" + } + } + }, + "Microsoft.Extensions.DependencyInjection.Abstractions/2.1.0": { + "runtime": { + "lib/netstandard2.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll": { + "assemblyVersion": "2.1.0.0", + "fileVersion": "2.1.0.18136" + } + } + }, + "Microsoft.NETCore.Platforms/1.1.0": {}, + "NETStandard.Library/2.0.3": { + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0" + } + }, + "Prise.IntegrationTestsContract/1.0.0": { + "runtime": { + "Prise.IntegrationTestsContract.dll": {} + } + }, + "Prise.Plugin/1.0.0": { + "dependencies": { + "Microsoft.Extensions.DependencyInjection": "2.1.0" + }, + "runtime": { + "Prise.Plugin.dll": {} + } + } + } + }, + "libraries": { + "PluginB/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "Microsoft.Extensions.DependencyInjection/2.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-gqQviLfuA31PheEGi+XJoZc1bc9H9RsPa9Gq9XuDct7XGWSR9eVXjK5Sg7CSUPhTFHSuxUFY12wcTYLZ4zM1hg==", + "path": "microsoft.extensions.dependencyinjection/2.1.0", + "hashPath": "microsoft.extensions.dependencyinjection.2.1.0.nupkg.sha512" + }, + "Microsoft.Extensions.DependencyInjection.Abstractions/2.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-8/CtASu80UIoyG+r8FstrmZW5GLtXxzoYpjj3jV0FKZCL5CiFgSH3pAmqut/dC68mu7N1bU6v0UtKKL3gCUQGQ==", + "path": "microsoft.extensions.dependencyinjection.abstractions/2.1.0", + "hashPath": "microsoft.extensions.dependencyinjection.abstractions.2.1.0.nupkg.sha512" + }, + "Microsoft.NETCore.Platforms/1.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-kz0PEW2lhqygehI/d6XsPCQzD7ff7gUJaVGPVETX611eadGsA3A877GdSlU0LRVMCTH/+P3o2iDTak+S08V2+A==", + "path": "microsoft.netcore.platforms/1.1.0", + "hashPath": "microsoft.netcore.platforms.1.1.0.nupkg.sha512" + }, + "NETStandard.Library/2.0.3": { + "type": "package", + "serviceable": true, + "sha512": "sha512-st47PosZSHrjECdjeIzZQbzivYBJFv6P2nv4cj2ypdI204DO+vZ7l5raGMiX4eXMJ53RfOIg+/s4DHVZ54Nu2A==", + "path": "netstandard.library/2.0.3", + "hashPath": "netstandard.library.2.0.3.nupkg.sha512" + }, + "Prise.IntegrationTestsContract/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "Prise.Plugin/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + } + } +} \ No newline at end of file diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginB/PluginB.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginB/PluginB.dll new file mode 100644 index 0000000..4772d0e Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginB/PluginB.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginB/PluginB.pdb b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginB/PluginB.pdb new file mode 100644 index 0000000..7af9b03 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginB/PluginB.pdb differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginB/Prise.IntegrationTestsContract.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginB/Prise.IntegrationTestsContract.dll new file mode 100644 index 0000000..8eb98f9 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginB/Prise.IntegrationTestsContract.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginB/Prise.IntegrationTestsContract.pdb b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginB/Prise.IntegrationTestsContract.pdb new file mode 100644 index 0000000..b42bf62 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginB/Prise.IntegrationTestsContract.pdb differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginB/Prise.Plugin.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginB/Prise.Plugin.dll new file mode 100644 index 0000000..12c6767 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginB/Prise.Plugin.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginB/Prise.Plugin.pdb b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginB/Prise.Plugin.pdb new file mode 100644 index 0000000..c153ddc Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginB/Prise.Plugin.pdb differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginC/DomainForPluginC.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginC/DomainForPluginC.dll new file mode 100644 index 0000000..ed9c58a Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginC/DomainForPluginC.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginC/DomainForPluginC.pdb b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginC/DomainForPluginC.pdb new file mode 100644 index 0000000..63cf896 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginC/DomainForPluginC.pdb differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginC/Microsoft.Extensions.DependencyInjection.Abstractions.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginC/Microsoft.Extensions.DependencyInjection.Abstractions.dll new file mode 100644 index 0000000..e557f9d Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginC/Microsoft.Extensions.DependencyInjection.Abstractions.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginC/Microsoft.Extensions.DependencyInjection.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginC/Microsoft.Extensions.DependencyInjection.dll new file mode 100644 index 0000000..4b653bd Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginC/Microsoft.Extensions.DependencyInjection.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginC/PluginC.deps.json b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginC/PluginC.deps.json new file mode 100644 index 0000000..96d4df0 --- /dev/null +++ b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginC/PluginC.deps.json @@ -0,0 +1,116 @@ +{ + "runtimeTarget": { + "name": ".NETStandard,Version=v2.0/", + "signature": "" + }, + "compilationOptions": {}, + "targets": { + ".NETStandard,Version=v2.0": {}, + ".NETStandard,Version=v2.0/": { + "PluginC/1.0.0": { + "dependencies": { + "DomainForPluginC": "1.0.0", + "NETStandard.Library": "2.0.3", + "Prise.IntegrationTestsContract": "1.0.0", + "Prise.Plugin": "1.0.0" + }, + "runtime": { + "PluginC.dll": {} + } + }, + "Microsoft.Extensions.DependencyInjection/2.1.0": { + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "2.1.0" + }, + "runtime": { + "lib/netstandard2.0/Microsoft.Extensions.DependencyInjection.dll": { + "assemblyVersion": "2.1.0.0", + "fileVersion": "2.1.0.18136" + } + } + }, + "Microsoft.Extensions.DependencyInjection.Abstractions/2.1.0": { + "runtime": { + "lib/netstandard2.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll": { + "assemblyVersion": "2.1.0.0", + "fileVersion": "2.1.0.18136" + } + } + }, + "Microsoft.NETCore.Platforms/1.1.0": {}, + "NETStandard.Library/2.0.3": { + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0" + } + }, + "DomainForPluginC/1.0.0": { + "runtime": { + "DomainForPluginC.dll": {} + } + }, + "Prise.IntegrationTestsContract/1.0.0": { + "runtime": { + "Prise.IntegrationTestsContract.dll": {} + } + }, + "Prise.Plugin/1.0.0": { + "dependencies": { + "Microsoft.Extensions.DependencyInjection": "2.1.0" + }, + "runtime": { + "Prise.Plugin.dll": {} + } + } + } + }, + "libraries": { + "PluginC/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "Microsoft.Extensions.DependencyInjection/2.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-gqQviLfuA31PheEGi+XJoZc1bc9H9RsPa9Gq9XuDct7XGWSR9eVXjK5Sg7CSUPhTFHSuxUFY12wcTYLZ4zM1hg==", + "path": "microsoft.extensions.dependencyinjection/2.1.0", + "hashPath": "microsoft.extensions.dependencyinjection.2.1.0.nupkg.sha512" + }, + "Microsoft.Extensions.DependencyInjection.Abstractions/2.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-8/CtASu80UIoyG+r8FstrmZW5GLtXxzoYpjj3jV0FKZCL5CiFgSH3pAmqut/dC68mu7N1bU6v0UtKKL3gCUQGQ==", + "path": "microsoft.extensions.dependencyinjection.abstractions/2.1.0", + "hashPath": "microsoft.extensions.dependencyinjection.abstractions.2.1.0.nupkg.sha512" + }, + "Microsoft.NETCore.Platforms/1.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-kz0PEW2lhqygehI/d6XsPCQzD7ff7gUJaVGPVETX611eadGsA3A877GdSlU0LRVMCTH/+P3o2iDTak+S08V2+A==", + "path": "microsoft.netcore.platforms/1.1.0", + "hashPath": "microsoft.netcore.platforms.1.1.0.nupkg.sha512" + }, + "NETStandard.Library/2.0.3": { + "type": "package", + "serviceable": true, + "sha512": "sha512-st47PosZSHrjECdjeIzZQbzivYBJFv6P2nv4cj2ypdI204DO+vZ7l5raGMiX4eXMJ53RfOIg+/s4DHVZ54Nu2A==", + "path": "netstandard.library/2.0.3", + "hashPath": "netstandard.library.2.0.3.nupkg.sha512" + }, + "DomainForPluginC/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "Prise.IntegrationTestsContract/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "Prise.Plugin/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + } + } +} \ No newline at end of file diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginC/PluginC.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginC/PluginC.dll new file mode 100644 index 0000000..cafa968 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginC/PluginC.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginC/PluginC.pdb b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginC/PluginC.pdb new file mode 100644 index 0000000..601fb50 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginC/PluginC.pdb differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginC/Prise.IntegrationTestsContract.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginC/Prise.IntegrationTestsContract.dll new file mode 100644 index 0000000..8eb98f9 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginC/Prise.IntegrationTestsContract.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginC/Prise.IntegrationTestsContract.pdb b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginC/Prise.IntegrationTestsContract.pdb new file mode 100644 index 0000000..b42bf62 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginC/Prise.IntegrationTestsContract.pdb differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginC/Prise.Plugin.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginC/Prise.Plugin.dll new file mode 100644 index 0000000..12c6767 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginC/Prise.Plugin.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginC/Prise.Plugin.pdb b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginC/Prise.Plugin.pdb new file mode 100644 index 0000000..c153ddc Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.0/PluginC/Prise.Plugin.pdb differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginA/Microsoft.Extensions.DependencyInjection.Abstractions.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginA/Microsoft.Extensions.DependencyInjection.Abstractions.dll new file mode 100644 index 0000000..e557f9d Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginA/Microsoft.Extensions.DependencyInjection.Abstractions.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginA/Microsoft.Extensions.DependencyInjection.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginA/Microsoft.Extensions.DependencyInjection.dll new file mode 100644 index 0000000..4b653bd Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginA/Microsoft.Extensions.DependencyInjection.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginA/PluginA.deps.json b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginA/PluginA.deps.json new file mode 100644 index 0000000..c7633a0 --- /dev/null +++ b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginA/PluginA.deps.json @@ -0,0 +1,84 @@ +{ + "runtimeTarget": { + "name": ".NETStandard,Version=v2.1/", + "signature": "" + }, + "compilationOptions": {}, + "targets": { + ".NETStandard,Version=v2.1": {}, + ".NETStandard,Version=v2.1/": { + "PluginA/1.0.0": { + "dependencies": { + "Prise.IntegrationTestsContract": "1.0.0", + "Prise.Plugin": "1.0.0" + }, + "runtime": { + "PluginA.dll": {} + } + }, + "Microsoft.Extensions.DependencyInjection/2.1.0": { + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "2.1.0" + }, + "runtime": { + "lib/netstandard2.0/Microsoft.Extensions.DependencyInjection.dll": { + "assemblyVersion": "2.1.0.0", + "fileVersion": "2.1.0.18136" + } + } + }, + "Microsoft.Extensions.DependencyInjection.Abstractions/2.1.0": { + "runtime": { + "lib/netstandard2.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll": { + "assemblyVersion": "2.1.0.0", + "fileVersion": "2.1.0.18136" + } + } + }, + "Prise.IntegrationTestsContract/1.0.0": { + "runtime": { + "Prise.IntegrationTestsContract.dll": {} + } + }, + "Prise.Plugin/1.0.0": { + "dependencies": { + "Microsoft.Extensions.DependencyInjection": "2.1.0" + }, + "runtime": { + "Prise.Plugin.dll": {} + } + } + } + }, + "libraries": { + "PluginA/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "Microsoft.Extensions.DependencyInjection/2.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-gqQviLfuA31PheEGi+XJoZc1bc9H9RsPa9Gq9XuDct7XGWSR9eVXjK5Sg7CSUPhTFHSuxUFY12wcTYLZ4zM1hg==", + "path": "microsoft.extensions.dependencyinjection/2.1.0", + "hashPath": "microsoft.extensions.dependencyinjection.2.1.0.nupkg.sha512" + }, + "Microsoft.Extensions.DependencyInjection.Abstractions/2.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-8/CtASu80UIoyG+r8FstrmZW5GLtXxzoYpjj3jV0FKZCL5CiFgSH3pAmqut/dC68mu7N1bU6v0UtKKL3gCUQGQ==", + "path": "microsoft.extensions.dependencyinjection.abstractions/2.1.0", + "hashPath": "microsoft.extensions.dependencyinjection.abstractions.2.1.0.nupkg.sha512" + }, + "Prise.IntegrationTestsContract/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "Prise.Plugin/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + } + } +} \ No newline at end of file diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginA/PluginA.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginA/PluginA.dll new file mode 100644 index 0000000..99aa89a Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginA/PluginA.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginA/PluginA.pdb b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginA/PluginA.pdb new file mode 100644 index 0000000..4a37e82 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginA/PluginA.pdb differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginA/Prise.IntegrationTestsContract.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginA/Prise.IntegrationTestsContract.dll new file mode 100644 index 0000000..0b8c181 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginA/Prise.IntegrationTestsContract.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginA/Prise.IntegrationTestsContract.pdb b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginA/Prise.IntegrationTestsContract.pdb new file mode 100644 index 0000000..dce1764 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginA/Prise.IntegrationTestsContract.pdb differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginA/Prise.Plugin.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginA/Prise.Plugin.dll new file mode 100644 index 0000000..bd80490 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginA/Prise.Plugin.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginA/Prise.Plugin.pdb b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginA/Prise.Plugin.pdb new file mode 100644 index 0000000..ae9bf94 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginA/Prise.Plugin.pdb differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginB/Microsoft.Extensions.DependencyInjection.Abstractions.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginB/Microsoft.Extensions.DependencyInjection.Abstractions.dll new file mode 100644 index 0000000..e557f9d Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginB/Microsoft.Extensions.DependencyInjection.Abstractions.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginB/Microsoft.Extensions.DependencyInjection.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginB/Microsoft.Extensions.DependencyInjection.dll new file mode 100644 index 0000000..4b653bd Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginB/Microsoft.Extensions.DependencyInjection.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginB/PluginB.deps.json b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginB/PluginB.deps.json new file mode 100644 index 0000000..6fdf53f --- /dev/null +++ b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginB/PluginB.deps.json @@ -0,0 +1,84 @@ +{ + "runtimeTarget": { + "name": ".NETStandard,Version=v2.1/", + "signature": "" + }, + "compilationOptions": {}, + "targets": { + ".NETStandard,Version=v2.1": {}, + ".NETStandard,Version=v2.1/": { + "PluginB/1.0.0": { + "dependencies": { + "Prise.IntegrationTestsContract": "1.0.0", + "Prise.Plugin": "1.0.0" + }, + "runtime": { + "PluginB.dll": {} + } + }, + "Microsoft.Extensions.DependencyInjection/2.1.0": { + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "2.1.0" + }, + "runtime": { + "lib/netstandard2.0/Microsoft.Extensions.DependencyInjection.dll": { + "assemblyVersion": "2.1.0.0", + "fileVersion": "2.1.0.18136" + } + } + }, + "Microsoft.Extensions.DependencyInjection.Abstractions/2.1.0": { + "runtime": { + "lib/netstandard2.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll": { + "assemblyVersion": "2.1.0.0", + "fileVersion": "2.1.0.18136" + } + } + }, + "Prise.IntegrationTestsContract/1.0.0": { + "runtime": { + "Prise.IntegrationTestsContract.dll": {} + } + }, + "Prise.Plugin/1.0.0": { + "dependencies": { + "Microsoft.Extensions.DependencyInjection": "2.1.0" + }, + "runtime": { + "Prise.Plugin.dll": {} + } + } + } + }, + "libraries": { + "PluginB/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "Microsoft.Extensions.DependencyInjection/2.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-gqQviLfuA31PheEGi+XJoZc1bc9H9RsPa9Gq9XuDct7XGWSR9eVXjK5Sg7CSUPhTFHSuxUFY12wcTYLZ4zM1hg==", + "path": "microsoft.extensions.dependencyinjection/2.1.0", + "hashPath": "microsoft.extensions.dependencyinjection.2.1.0.nupkg.sha512" + }, + "Microsoft.Extensions.DependencyInjection.Abstractions/2.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-8/CtASu80UIoyG+r8FstrmZW5GLtXxzoYpjj3jV0FKZCL5CiFgSH3pAmqut/dC68mu7N1bU6v0UtKKL3gCUQGQ==", + "path": "microsoft.extensions.dependencyinjection.abstractions/2.1.0", + "hashPath": "microsoft.extensions.dependencyinjection.abstractions.2.1.0.nupkg.sha512" + }, + "Prise.IntegrationTestsContract/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "Prise.Plugin/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + } + } +} \ No newline at end of file diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginB/PluginB.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginB/PluginB.dll new file mode 100644 index 0000000..dea9c74 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginB/PluginB.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginB/PluginB.pdb b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginB/PluginB.pdb new file mode 100644 index 0000000..b9d2b31 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginB/PluginB.pdb differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginB/Prise.IntegrationTestsContract.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginB/Prise.IntegrationTestsContract.dll new file mode 100644 index 0000000..0b8c181 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginB/Prise.IntegrationTestsContract.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginB/Prise.IntegrationTestsContract.pdb b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginB/Prise.IntegrationTestsContract.pdb new file mode 100644 index 0000000..dce1764 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginB/Prise.IntegrationTestsContract.pdb differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginB/Prise.Plugin.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginB/Prise.Plugin.dll new file mode 100644 index 0000000..bd80490 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginB/Prise.Plugin.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginB/Prise.Plugin.pdb b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginB/Prise.Plugin.pdb new file mode 100644 index 0000000..ae9bf94 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginB/Prise.Plugin.pdb differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginDWithFactory/Dictionary.Domain.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginDWithFactory/Dictionary.Domain.dll new file mode 100644 index 0000000..d2dddce Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginDWithFactory/Dictionary.Domain.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginDWithFactory/Dictionary.Domain.pdb b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginDWithFactory/Dictionary.Domain.pdb new file mode 100644 index 0000000..0c186f5 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginDWithFactory/Dictionary.Domain.pdb differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginDWithFactory/ExternalServiceForPluginD.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginDWithFactory/ExternalServiceForPluginD.dll new file mode 100644 index 0000000..6cd2f16 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginDWithFactory/ExternalServiceForPluginD.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginDWithFactory/ExternalServiceForPluginD.pdb b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginDWithFactory/ExternalServiceForPluginD.pdb new file mode 100644 index 0000000..a3a9132 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginDWithFactory/ExternalServiceForPluginD.pdb differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginDWithFactory/Microsoft.Bcl.AsyncInterfaces.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginDWithFactory/Microsoft.Bcl.AsyncInterfaces.dll new file mode 100644 index 0000000..c695bdd Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginDWithFactory/Microsoft.Bcl.AsyncInterfaces.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginDWithFactory/Microsoft.Extensions.Configuration.Abstractions.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginDWithFactory/Microsoft.Extensions.Configuration.Abstractions.dll new file mode 100644 index 0000000..2ce4c75 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginDWithFactory/Microsoft.Extensions.Configuration.Abstractions.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginDWithFactory/Microsoft.Extensions.DependencyInjection.Abstractions.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginDWithFactory/Microsoft.Extensions.DependencyInjection.Abstractions.dll new file mode 100644 index 0000000..e557f9d Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginDWithFactory/Microsoft.Extensions.DependencyInjection.Abstractions.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginDWithFactory/Microsoft.Extensions.DependencyInjection.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginDWithFactory/Microsoft.Extensions.DependencyInjection.dll new file mode 100644 index 0000000..4b653bd Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginDWithFactory/Microsoft.Extensions.DependencyInjection.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginDWithFactory/Microsoft.Extensions.Primitives.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginDWithFactory/Microsoft.Extensions.Primitives.dll new file mode 100644 index 0000000..c634db2 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginDWithFactory/Microsoft.Extensions.Primitives.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginDWithFactory/Newtonsoft.Json.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginDWithFactory/Newtonsoft.Json.dll new file mode 100644 index 0000000..e2118f9 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginDWithFactory/Newtonsoft.Json.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginDWithFactory/PluginD.deps.json b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginDWithFactory/PluginD.deps.json new file mode 100644 index 0000000..ae4d360 --- /dev/null +++ b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginDWithFactory/PluginD.deps.json @@ -0,0 +1,332 @@ +{ + "runtimeTarget": { + "name": ".NETStandard,Version=v2.1/", + "signature": "" + }, + "compilationOptions": {}, + "targets": { + ".NETStandard,Version=v2.1": {}, + ".NETStandard,Version=v2.1/": { + "PluginD/1.0.0": { + "dependencies": { + "Dictionary.Domain": "1.0.0", + "ExternalServiceForPluginD": "1.0.0", + "Microsoft.Extensions.Configuration.Abstractions": "3.1.0", + "Prise.IntegrationTestsContract": "1.0.0", + "Prise.Plugin": "1.0.0", + "Prise.PluginBridge": "1.0.0" + }, + "runtime": { + "PluginD.dll": {} + } + }, + "Microsoft.Bcl.AsyncInterfaces/1.1.0": { + "dependencies": { + "System.Threading.Tasks.Extensions": "4.5.2" + }, + "runtime": { + "lib/netstandard2.1/Microsoft.Bcl.AsyncInterfaces.dll": { + "assemblyVersion": "1.0.0.0", + "fileVersion": "4.700.19.56404" + } + } + }, + "Microsoft.Extensions.Configuration.Abstractions/3.1.0": { + "dependencies": { + "Microsoft.Extensions.Primitives": "3.1.0" + }, + "runtime": { + "lib/netstandard2.0/Microsoft.Extensions.Configuration.Abstractions.dll": { + "assemblyVersion": "3.1.0.0", + "fileVersion": "3.100.19.56504" + } + } + }, + "Microsoft.Extensions.DependencyInjection/2.1.0": { + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "2.1.0" + }, + "runtime": { + "lib/netstandard2.0/Microsoft.Extensions.DependencyInjection.dll": { + "assemblyVersion": "2.1.0.0", + "fileVersion": "2.1.0.18136" + } + } + }, + "Microsoft.Extensions.DependencyInjection.Abstractions/2.1.0": { + "runtime": { + "lib/netstandard2.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll": { + "assemblyVersion": "2.1.0.0", + "fileVersion": "2.1.0.18136" + } + } + }, + "Microsoft.Extensions.Primitives/3.1.0": { + "dependencies": { + "System.Memory": "4.5.3", + "System.Runtime.CompilerServices.Unsafe": "4.7.0" + }, + "runtime": { + "lib/netstandard2.0/Microsoft.Extensions.Primitives.dll": { + "assemblyVersion": "3.1.0.0", + "fileVersion": "3.100.19.56504" + } + } + }, + "Newtonsoft.Json/11.0.2": { + "runtime": { + "lib/netstandard2.0/Newtonsoft.Json.dll": { + "assemblyVersion": "11.0.0.0", + "fileVersion": "11.0.2.21924" + } + } + }, + "System.Buffers/4.5.0": { + "runtime": { + "lib/netstandard2.0/System.Buffers.dll": { + "assemblyVersion": "4.0.3.0", + "fileVersion": "4.6.26515.6" + } + } + }, + "System.Memory/4.5.3": { + "dependencies": { + "System.Buffers": "4.5.0", + "System.Numerics.Vectors": "4.5.0", + "System.Runtime.CompilerServices.Unsafe": "4.7.0" + }, + "runtime": { + "lib/netstandard2.0/System.Memory.dll": { + "assemblyVersion": "4.0.1.1", + "fileVersion": "4.6.27617.2" + } + } + }, + "System.Numerics.Vectors/4.5.0": { + "runtime": { + "lib/netstandard2.0/System.Numerics.Vectors.dll": { + "assemblyVersion": "4.1.4.0", + "fileVersion": "4.6.26515.6" + } + } + }, + "System.Reflection.DispatchProxy/4.7.0": { + "runtime": { + "lib/netstandard2.0/System.Reflection.DispatchProxy.dll": { + "assemblyVersion": "4.0.6.0", + "fileVersion": "4.700.19.56404" + } + } + }, + "System.Runtime.CompilerServices.Unsafe/4.7.0": { + "runtime": { + "lib/netstandard2.0/System.Runtime.CompilerServices.Unsafe.dll": { + "assemblyVersion": "4.0.6.0", + "fileVersion": "4.700.19.56404" + } + } + }, + "System.Text.Encodings.Web/4.7.0": { + "runtime": { + "lib/netstandard2.1/System.Text.Encodings.Web.dll": { + "assemblyVersion": "4.0.5.0", + "fileVersion": "4.700.19.56404" + } + } + }, + "System.Text.Json/4.7.0": { + "dependencies": { + "Microsoft.Bcl.AsyncInterfaces": "1.1.0", + "System.Buffers": "4.5.0", + "System.Memory": "4.5.3", + "System.Numerics.Vectors": "4.5.0", + "System.Runtime.CompilerServices.Unsafe": "4.7.0", + "System.Text.Encodings.Web": "4.7.0", + "System.Threading.Tasks.Extensions": "4.5.2" + }, + "runtime": { + "lib/netstandard2.0/System.Text.Json.dll": { + "assemblyVersion": "4.0.1.0", + "fileVersion": "4.700.19.56404" + } + } + }, + "System.Threading.Tasks.Extensions/4.5.2": { + "dependencies": { + "System.Runtime.CompilerServices.Unsafe": "4.7.0" + }, + "runtime": { + "lib/netstandard2.0/System.Threading.Tasks.Extensions.dll": { + "assemblyVersion": "4.2.0.0", + "fileVersion": "4.6.27129.4" + } + } + }, + "Dictionary.Domain/1.0.0": { + "dependencies": { + "Newtonsoft.Json": "11.0.2" + }, + "runtime": { + "Dictionary.Domain.dll": {} + } + }, + "ExternalServiceForPluginD/1.0.0": { + "runtime": { + "ExternalServiceForPluginD.dll": {} + } + }, + "Prise.IntegrationTestsContract/1.0.0": { + "runtime": { + "Prise.IntegrationTestsContract.dll": {} + } + }, + "Prise.Plugin/1.0.0": { + "dependencies": { + "Microsoft.Extensions.DependencyInjection": "2.1.0" + }, + "runtime": { + "Prise.Plugin.dll": {} + } + }, + "Prise.PluginBridge/1.0.0": { + "dependencies": { + "System.Reflection.DispatchProxy": "4.7.0", + "System.Text.Json": "4.7.0" + }, + "runtime": { + "Prise.PluginBridge.dll": {} + } + } + } + }, + "libraries": { + "PluginD/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "Microsoft.Bcl.AsyncInterfaces/1.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-1Am6l4Vpn3/K32daEqZI+FFr96OlZkgwK2LcT3pZ2zWubR5zTPW3/FkO1Rat9kb7oQOa4rxgl9LJHc5tspCWfg==", + "path": "microsoft.bcl.asyncinterfaces/1.1.0", + "hashPath": "microsoft.bcl.asyncinterfaces.1.1.0.nupkg.sha512" + }, + "Microsoft.Extensions.Configuration.Abstractions/3.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-ESz6bVoDQX7sgWdKHF6G9Pq672T8k+19AFb/txDXwdz7MoqaNQj2/in3agm/3qae9V+WvQZH86LLTNVo0it8vQ==", + "path": "microsoft.extensions.configuration.abstractions/3.1.0", + "hashPath": "microsoft.extensions.configuration.abstractions.3.1.0.nupkg.sha512" + }, + "Microsoft.Extensions.DependencyInjection/2.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-gqQviLfuA31PheEGi+XJoZc1bc9H9RsPa9Gq9XuDct7XGWSR9eVXjK5Sg7CSUPhTFHSuxUFY12wcTYLZ4zM1hg==", + "path": "microsoft.extensions.dependencyinjection/2.1.0", + "hashPath": "microsoft.extensions.dependencyinjection.2.1.0.nupkg.sha512" + }, + "Microsoft.Extensions.DependencyInjection.Abstractions/2.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-8/CtASu80UIoyG+r8FstrmZW5GLtXxzoYpjj3jV0FKZCL5CiFgSH3pAmqut/dC68mu7N1bU6v0UtKKL3gCUQGQ==", + "path": "microsoft.extensions.dependencyinjection.abstractions/2.1.0", + "hashPath": "microsoft.extensions.dependencyinjection.abstractions.2.1.0.nupkg.sha512" + }, + "Microsoft.Extensions.Primitives/3.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-LEKAnX7lhUhSoIc2XraCTK3M4IU/LdVUzCe464Sa4+7F4ZJuXHHRzZli2mDbiT4xzAZhgqXbvfnb5+CNDcQFfg==", + "path": "microsoft.extensions.primitives/3.1.0", + "hashPath": "microsoft.extensions.primitives.3.1.0.nupkg.sha512" + }, + "Newtonsoft.Json/11.0.2": { + "type": "package", + "serviceable": true, + "sha512": "sha512-IvJe1pj7JHEsP8B8J8DwlMEx8UInrs/x+9oVY+oCD13jpLu4JbJU2WCIsMRn5C4yW9+DgkaO8uiVE5VHKjpmdQ==", + "path": "newtonsoft.json/11.0.2", + "hashPath": "newtonsoft.json.11.0.2.nupkg.sha512" + }, + "System.Buffers/4.5.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-pL2ChpaRRWI/p4LXyy4RgeWlYF2sgfj/pnVMvBqwNFr5cXg7CXNnWZWxrOONLg8VGdFB8oB+EG2Qw4MLgTOe+A==", + "path": "system.buffers/4.5.0", + "hashPath": "system.buffers.4.5.0.nupkg.sha512" + }, + "System.Memory/4.5.3": { + "type": "package", + "serviceable": true, + "sha512": "sha512-3oDzvc/zzetpTKWMShs1AADwZjQ/36HnsufHRPcOjyRAAMLDlu2iD33MBI2opxnezcVUtXyqDXXjoFMOU9c7SA==", + "path": "system.memory/4.5.3", + "hashPath": "system.memory.4.5.3.nupkg.sha512" + }, + "System.Numerics.Vectors/4.5.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-QQTlPTl06J/iiDbJCiepZ4H//BVraReU4O4EoRw1U02H5TLUIT7xn3GnDp9AXPSlJUDyFs4uWjWafNX6WrAojQ==", + "path": "system.numerics.vectors/4.5.0", + "hashPath": "system.numerics.vectors.4.5.0.nupkg.sha512" + }, + "System.Reflection.DispatchProxy/4.7.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-zZ+An2QZWOsNP+T+ft3/b5Xm1+6mELT5c+OOTUlt3oh0+BUKI6M0bvMA75t/uMxwfav/qy4ZoUCZ+SDaekTwTA==", + "path": "system.reflection.dispatchproxy/4.7.0", + "hashPath": "system.reflection.dispatchproxy.4.7.0.nupkg.sha512" + }, + "System.Runtime.CompilerServices.Unsafe/4.7.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-IpU1lcHz8/09yDr9N+Juc7SCgNUz+RohkCQI+KsWKR67XxpFr8Z6c8t1iENCXZuRuNCc4HBwme/MDHNVCwyAKg==", + "path": "system.runtime.compilerservices.unsafe/4.7.0", + "hashPath": "system.runtime.compilerservices.unsafe.4.7.0.nupkg.sha512" + }, + "System.Text.Encodings.Web/4.7.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-IJanJWPQvya2sbGStt3Fkdy4IaomUBSadAfYWeJDQw0zclMk9ixSvMeei6cSmTTQ6ZkGIIAbhHZVCoLR7GgX7Q==", + "path": "system.text.encodings.web/4.7.0", + "hashPath": "system.text.encodings.web.4.7.0.nupkg.sha512" + }, + "System.Text.Json/4.7.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-IPq/x/d5nAcnD3vIyM3AbPOaTgcqrh0AqPSx7U53UFu3M6k1TH1u/eXc9/h4jm/3mpP1WRUpevlPY4PACd7AWw==", + "path": "system.text.json/4.7.0", + "hashPath": "system.text.json.4.7.0.nupkg.sha512" + }, + "System.Threading.Tasks.Extensions/4.5.2": { + "type": "package", + "serviceable": true, + "sha512": "sha512-BG/TNxDFv0svAzx8OiMXDlsHfGw623BZ8tCXw4YLhDFDvDhNUEV58jKYMGRnkbJNm7c3JNNJDiN7JBMzxRBR2w==", + "path": "system.threading.tasks.extensions/4.5.2", + "hashPath": "system.threading.tasks.extensions.4.5.2.nupkg.sha512" + }, + "Dictionary.Domain/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "ExternalServiceForPluginD/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "Prise.IntegrationTestsContract/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "Prise.Plugin/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "Prise.PluginBridge/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + } + } +} \ No newline at end of file diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginDWithFactory/PluginD.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginDWithFactory/PluginD.dll new file mode 100644 index 0000000..a66a4e4 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginDWithFactory/PluginD.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginDWithFactory/PluginD.pdb b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginDWithFactory/PluginD.pdb new file mode 100644 index 0000000..32589f7 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginDWithFactory/PluginD.pdb differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginDWithFactory/Prise.IntegrationTestsContract.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginDWithFactory/Prise.IntegrationTestsContract.dll new file mode 100644 index 0000000..0b8c181 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginDWithFactory/Prise.IntegrationTestsContract.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginDWithFactory/Prise.IntegrationTestsContract.pdb b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginDWithFactory/Prise.IntegrationTestsContract.pdb new file mode 100644 index 0000000..dce1764 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginDWithFactory/Prise.IntegrationTestsContract.pdb differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginDWithFactory/Prise.Plugin.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginDWithFactory/Prise.Plugin.dll new file mode 100644 index 0000000..bd80490 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginDWithFactory/Prise.Plugin.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginDWithFactory/Prise.Plugin.pdb b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginDWithFactory/Prise.Plugin.pdb new file mode 100644 index 0000000..ae9bf94 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginDWithFactory/Prise.Plugin.pdb differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginDWithFactory/Prise.PluginBridge.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginDWithFactory/Prise.PluginBridge.dll new file mode 100644 index 0000000..fe4c3c5 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginDWithFactory/Prise.PluginBridge.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginDWithFactory/Prise.PluginBridge.pdb b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginDWithFactory/Prise.PluginBridge.pdb new file mode 100644 index 0000000..cf3caa5 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginDWithFactory/Prise.PluginBridge.pdb differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginDWithFactory/System.Buffers.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginDWithFactory/System.Buffers.dll new file mode 100644 index 0000000..c517a3b Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginDWithFactory/System.Buffers.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginDWithFactory/System.Memory.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginDWithFactory/System.Memory.dll new file mode 100644 index 0000000..bdfc501 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginDWithFactory/System.Memory.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginDWithFactory/System.Numerics.Vectors.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginDWithFactory/System.Numerics.Vectors.dll new file mode 100644 index 0000000..1020577 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginDWithFactory/System.Numerics.Vectors.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginDWithFactory/System.Reflection.DispatchProxy.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginDWithFactory/System.Reflection.DispatchProxy.dll new file mode 100644 index 0000000..ef17298 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginDWithFactory/System.Reflection.DispatchProxy.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginDWithFactory/System.Runtime.CompilerServices.Unsafe.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginDWithFactory/System.Runtime.CompilerServices.Unsafe.dll new file mode 100644 index 0000000..c66b445 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginDWithFactory/System.Runtime.CompilerServices.Unsafe.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginDWithFactory/System.Text.Encodings.Web.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginDWithFactory/System.Text.Encodings.Web.dll new file mode 100644 index 0000000..778261a Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginDWithFactory/System.Text.Encodings.Web.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginDWithFactory/System.Text.Json.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginDWithFactory/System.Text.Json.dll new file mode 100644 index 0000000..a3dd2eb Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginDWithFactory/System.Text.Json.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginDWithFactory/System.Threading.Tasks.Extensions.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginDWithFactory/System.Threading.Tasks.Extensions.dll new file mode 100644 index 0000000..a99c907 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginDWithFactory/System.Threading.Tasks.Extensions.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginE/Microsoft.Bcl.AsyncInterfaces.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginE/Microsoft.Bcl.AsyncInterfaces.dll new file mode 100644 index 0000000..c695bdd Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginE/Microsoft.Bcl.AsyncInterfaces.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginE/Microsoft.Extensions.DependencyInjection.Abstractions.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginE/Microsoft.Extensions.DependencyInjection.Abstractions.dll new file mode 100644 index 0000000..e557f9d Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginE/Microsoft.Extensions.DependencyInjection.Abstractions.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginE/Microsoft.Extensions.DependencyInjection.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginE/Microsoft.Extensions.DependencyInjection.dll new file mode 100644 index 0000000..4b653bd Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginE/Microsoft.Extensions.DependencyInjection.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginE/PluginE.deps.json b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginE/PluginE.deps.json new file mode 100644 index 0000000..eeb993c --- /dev/null +++ b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginE/PluginE.deps.json @@ -0,0 +1,225 @@ +{ + "runtimeTarget": { + "name": ".NETStandard,Version=v2.1/", + "signature": "" + }, + "compilationOptions": {}, + "targets": { + ".NETStandard,Version=v2.1": {}, + ".NETStandard,Version=v2.1/": { + "PluginE/1.0.0": { + "dependencies": { + "Prise.IntegrationTestsContract": "1.0.0", + "Prise.Plugin": "1.0.0", + "System.Text.Json": "4.7.0" + }, + "runtime": { + "PluginE.dll": {} + } + }, + "Microsoft.Bcl.AsyncInterfaces/1.1.0": { + "dependencies": { + "System.Threading.Tasks.Extensions": "4.5.2" + }, + "runtime": { + "lib/netstandard2.1/Microsoft.Bcl.AsyncInterfaces.dll": { + "assemblyVersion": "1.0.0.0", + "fileVersion": "4.700.19.56404" + } + } + }, + "Microsoft.Extensions.DependencyInjection/2.1.0": { + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "2.1.0" + }, + "runtime": { + "lib/netstandard2.0/Microsoft.Extensions.DependencyInjection.dll": { + "assemblyVersion": "2.1.0.0", + "fileVersion": "2.1.0.18136" + } + } + }, + "Microsoft.Extensions.DependencyInjection.Abstractions/2.1.0": { + "runtime": { + "lib/netstandard2.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll": { + "assemblyVersion": "2.1.0.0", + "fileVersion": "2.1.0.18136" + } + } + }, + "System.Buffers/4.5.0": { + "runtime": { + "lib/netstandard2.0/System.Buffers.dll": { + "assemblyVersion": "4.0.3.0", + "fileVersion": "4.6.26515.6" + } + } + }, + "System.Memory/4.5.3": { + "dependencies": { + "System.Buffers": "4.5.0", + "System.Numerics.Vectors": "4.5.0", + "System.Runtime.CompilerServices.Unsafe": "4.7.0" + }, + "runtime": { + "lib/netstandard2.0/System.Memory.dll": { + "assemblyVersion": "4.0.1.1", + "fileVersion": "4.6.27617.2" + } + } + }, + "System.Numerics.Vectors/4.5.0": { + "runtime": { + "lib/netstandard2.0/System.Numerics.Vectors.dll": { + "assemblyVersion": "4.1.4.0", + "fileVersion": "4.6.26515.6" + } + } + }, + "System.Runtime.CompilerServices.Unsafe/4.7.0": { + "runtime": { + "lib/netstandard2.0/System.Runtime.CompilerServices.Unsafe.dll": { + "assemblyVersion": "4.0.6.0", + "fileVersion": "4.700.19.56404" + } + } + }, + "System.Text.Encodings.Web/4.7.0": { + "runtime": { + "lib/netstandard2.1/System.Text.Encodings.Web.dll": { + "assemblyVersion": "4.0.5.0", + "fileVersion": "4.700.19.56404" + } + } + }, + "System.Text.Json/4.7.0": { + "dependencies": { + "Microsoft.Bcl.AsyncInterfaces": "1.1.0", + "System.Buffers": "4.5.0", + "System.Memory": "4.5.3", + "System.Numerics.Vectors": "4.5.0", + "System.Runtime.CompilerServices.Unsafe": "4.7.0", + "System.Text.Encodings.Web": "4.7.0", + "System.Threading.Tasks.Extensions": "4.5.2" + }, + "runtime": { + "lib/netstandard2.0/System.Text.Json.dll": { + "assemblyVersion": "4.0.1.0", + "fileVersion": "4.700.19.56404" + } + } + }, + "System.Threading.Tasks.Extensions/4.5.2": { + "dependencies": { + "System.Runtime.CompilerServices.Unsafe": "4.7.0" + }, + "runtime": { + "lib/netstandard2.0/System.Threading.Tasks.Extensions.dll": { + "assemblyVersion": "4.2.0.0", + "fileVersion": "4.6.27129.4" + } + } + }, + "Prise.IntegrationTestsContract/1.0.0": { + "runtime": { + "Prise.IntegrationTestsContract.dll": {} + } + }, + "Prise.Plugin/1.0.0": { + "dependencies": { + "Microsoft.Extensions.DependencyInjection": "2.1.0" + }, + "runtime": { + "Prise.Plugin.dll": {} + } + } + } + }, + "libraries": { + "PluginE/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "Microsoft.Bcl.AsyncInterfaces/1.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-1Am6l4Vpn3/K32daEqZI+FFr96OlZkgwK2LcT3pZ2zWubR5zTPW3/FkO1Rat9kb7oQOa4rxgl9LJHc5tspCWfg==", + "path": "microsoft.bcl.asyncinterfaces/1.1.0", + "hashPath": "microsoft.bcl.asyncinterfaces.1.1.0.nupkg.sha512" + }, + "Microsoft.Extensions.DependencyInjection/2.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-gqQviLfuA31PheEGi+XJoZc1bc9H9RsPa9Gq9XuDct7XGWSR9eVXjK5Sg7CSUPhTFHSuxUFY12wcTYLZ4zM1hg==", + "path": "microsoft.extensions.dependencyinjection/2.1.0", + "hashPath": "microsoft.extensions.dependencyinjection.2.1.0.nupkg.sha512" + }, + "Microsoft.Extensions.DependencyInjection.Abstractions/2.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-8/CtASu80UIoyG+r8FstrmZW5GLtXxzoYpjj3jV0FKZCL5CiFgSH3pAmqut/dC68mu7N1bU6v0UtKKL3gCUQGQ==", + "path": "microsoft.extensions.dependencyinjection.abstractions/2.1.0", + "hashPath": "microsoft.extensions.dependencyinjection.abstractions.2.1.0.nupkg.sha512" + }, + "System.Buffers/4.5.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-pL2ChpaRRWI/p4LXyy4RgeWlYF2sgfj/pnVMvBqwNFr5cXg7CXNnWZWxrOONLg8VGdFB8oB+EG2Qw4MLgTOe+A==", + "path": "system.buffers/4.5.0", + "hashPath": "system.buffers.4.5.0.nupkg.sha512" + }, + "System.Memory/4.5.3": { + "type": "package", + "serviceable": true, + "sha512": "sha512-3oDzvc/zzetpTKWMShs1AADwZjQ/36HnsufHRPcOjyRAAMLDlu2iD33MBI2opxnezcVUtXyqDXXjoFMOU9c7SA==", + "path": "system.memory/4.5.3", + "hashPath": "system.memory.4.5.3.nupkg.sha512" + }, + "System.Numerics.Vectors/4.5.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-QQTlPTl06J/iiDbJCiepZ4H//BVraReU4O4EoRw1U02H5TLUIT7xn3GnDp9AXPSlJUDyFs4uWjWafNX6WrAojQ==", + "path": "system.numerics.vectors/4.5.0", + "hashPath": "system.numerics.vectors.4.5.0.nupkg.sha512" + }, + "System.Runtime.CompilerServices.Unsafe/4.7.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-IpU1lcHz8/09yDr9N+Juc7SCgNUz+RohkCQI+KsWKR67XxpFr8Z6c8t1iENCXZuRuNCc4HBwme/MDHNVCwyAKg==", + "path": "system.runtime.compilerservices.unsafe/4.7.0", + "hashPath": "system.runtime.compilerservices.unsafe.4.7.0.nupkg.sha512" + }, + "System.Text.Encodings.Web/4.7.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-IJanJWPQvya2sbGStt3Fkdy4IaomUBSadAfYWeJDQw0zclMk9ixSvMeei6cSmTTQ6ZkGIIAbhHZVCoLR7GgX7Q==", + "path": "system.text.encodings.web/4.7.0", + "hashPath": "system.text.encodings.web.4.7.0.nupkg.sha512" + }, + "System.Text.Json/4.7.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-IPq/x/d5nAcnD3vIyM3AbPOaTgcqrh0AqPSx7U53UFu3M6k1TH1u/eXc9/h4jm/3mpP1WRUpevlPY4PACd7AWw==", + "path": "system.text.json/4.7.0", + "hashPath": "system.text.json.4.7.0.nupkg.sha512" + }, + "System.Threading.Tasks.Extensions/4.5.2": { + "type": "package", + "serviceable": true, + "sha512": "sha512-BG/TNxDFv0svAzx8OiMXDlsHfGw623BZ8tCXw4YLhDFDvDhNUEV58jKYMGRnkbJNm7c3JNNJDiN7JBMzxRBR2w==", + "path": "system.threading.tasks.extensions/4.5.2", + "hashPath": "system.threading.tasks.extensions.4.5.2.nupkg.sha512" + }, + "Prise.IntegrationTestsContract/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "Prise.Plugin/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + } + } +} \ No newline at end of file diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginE/PluginE.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginE/PluginE.dll new file mode 100644 index 0000000..ec5e108 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginE/PluginE.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginE/PluginE.pdb b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginE/PluginE.pdb new file mode 100644 index 0000000..9fb0231 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginE/PluginE.pdb differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginE/Prise.IntegrationTestsContract.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginE/Prise.IntegrationTestsContract.dll new file mode 100644 index 0000000..0b8c181 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginE/Prise.IntegrationTestsContract.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginE/Prise.IntegrationTestsContract.pdb b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginE/Prise.IntegrationTestsContract.pdb new file mode 100644 index 0000000..dce1764 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginE/Prise.IntegrationTestsContract.pdb differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginE/Prise.Plugin.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginE/Prise.Plugin.dll new file mode 100644 index 0000000..bd80490 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginE/Prise.Plugin.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginE/Prise.Plugin.pdb b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginE/Prise.Plugin.pdb new file mode 100644 index 0000000..ae9bf94 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginE/Prise.Plugin.pdb differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginE/System.Buffers.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginE/System.Buffers.dll new file mode 100644 index 0000000..c517a3b Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginE/System.Buffers.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginE/System.Memory.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginE/System.Memory.dll new file mode 100644 index 0000000..bdfc501 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginE/System.Memory.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginE/System.Numerics.Vectors.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginE/System.Numerics.Vectors.dll new file mode 100644 index 0000000..1020577 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginE/System.Numerics.Vectors.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginE/System.Runtime.CompilerServices.Unsafe.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginE/System.Runtime.CompilerServices.Unsafe.dll new file mode 100644 index 0000000..c66b445 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginE/System.Runtime.CompilerServices.Unsafe.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginE/System.Text.Encodings.Web.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginE/System.Text.Encodings.Web.dll new file mode 100644 index 0000000..778261a Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginE/System.Text.Encodings.Web.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginE/System.Text.Json.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginE/System.Text.Json.dll new file mode 100644 index 0000000..a3dd2eb Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginE/System.Text.Json.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginE/System.Threading.Tasks.Extensions.dll b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginE/System.Threading.Tasks.Extensions.dll new file mode 100644 index 0000000..a99c907 Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginE/System.Threading.Tasks.Extensions.dll differ diff --git a/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginG.1.0.0.nupkg b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginG.1.0.0.nupkg new file mode 100644 index 0000000..9ff3d6d Binary files /dev/null and b/Vendor/Prise.Tests.Integration/compatibility/netstandard2.1/PluginG.1.0.0.nupkg differ diff --git a/Vendor/Prise.Tests/.vscode/settings.json b/Vendor/Prise.Tests/.vscode/settings.json new file mode 100644 index 0000000..3498c61 --- /dev/null +++ b/Vendor/Prise.Tests/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "dotnet-test-explorer.testProjectPath": "." +} \ No newline at end of file diff --git a/Vendor/Prise.Tests/Activation/DefaultPluginActivationContextProviderTests.cs b/Vendor/Prise.Tests/Activation/DefaultPluginActivationContextProviderTests.cs new file mode 100644 index 0000000..3f6e22b --- /dev/null +++ b/Vendor/Prise.Tests/Activation/DefaultPluginActivationContextProviderTests.cs @@ -0,0 +1,321 @@ + +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Moq; +using Prise.Activation; +using Prise.AssemblyLoading; +using Prise.AssemblyScanning; + +using Prise.Plugin; +using Prise.Tests.Plugins; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Threading.Tasks; + +namespace Prise.Tests.Activation +{ + [TestClass] + public class DefaultPluginActivationContextProviderTests : TestBase + { + [TestMethod] + public void Ctor_Works() + { + Assert.IsNotNull(new DefaultPluginActivationContextProvider()); + } + + //TODO More Tests + + private Type GetContract() + { + return TestableTypeBuilder.New() + .WithName("IMyTestType") + .WithNamespace("Test.Type") + .Build(); + } + + private CustomAttributeData GetPluginAttributeForContract(Type contract) + { + return TestableAttributeBuilder.New() + .WithAttributeType(typeof(Prise.Plugin.PluginAttribute)) + .WithNamedAgrument("PluginType", contract) + .Build(); + } + + [TestMethod] + public void ProvideActivationContext_Works() + { + var assemblyShim = this.mockRepository.Create(); + var contract = GetContract(); + var pluginAttribute = GetPluginAttributeForContract(contract); + + var typeName = "MyTestType"; + var testableType = TestableTypeBuilder.New() + .WithCustomAttributes(pluginAttribute) + .WithName(typeName) + .WithNamespace("Test.Type") + .Build(); + + // NO factory method + // NO activated method + // NO bootstrapper + // NO services + + assemblyShim.Setup(a => a.Types).Returns(new[] { testableType }); + + var sut = new DefaultPluginActivationContextProvider(); + var result = sut.ProvideActivationContext(testableType, assemblyShim.Object); + + Assert.IsNotNull(result); + Assert.IsNull(result.PluginActivatedMethod); + Assert.IsNull(result.PluginFactoryMethod); + Assert.AreEqual(0, result.PluginServices.Count()); + Assert.AreEqual(typeName, result.PluginType.Name); + } + + [TestMethod] + public void ProvideActivationContext_WithFactoryMethod_Works() + { + var assemblyShim = this.mockRepository.Create(); + var contract = GetContract(); + var pluginAttribute = GetPluginAttributeForContract(contract); + + // Factory method + var factoryMethodName = "This_Is_The_Factory_Method"; + var factoryMethod = TestableMethodInfoBuilder.New() + .WithName(factoryMethodName) + .WithAttribute(TestableAttributeBuilder.New() + .WithAttributeType(typeof(Prise.Plugin.PluginFactoryAttribute)).Build()) + .Build(); + + var typeName = "MyTestType"; + var testableType = TestableTypeBuilder.New() + .WithCustomAttributes(pluginAttribute) + .WithName(typeName) + .WithNamespace("Test.Type") + .WithMethods(factoryMethod) + .Build(); + + // NO activated method + // NO bootstrapper + // NO services + + assemblyShim.Setup(a => a.Types).Returns(new[] { testableType }); + + var sut = new DefaultPluginActivationContextProvider(); + var result = sut.ProvideActivationContext(testableType, assemblyShim.Object); + + Assert.IsNotNull(result); + Assert.IsNull(result.PluginActivatedMethod); + Assert.IsNotNull(result.PluginFactoryMethod); + Assert.AreEqual(factoryMethodName, result.PluginFactoryMethod.Name); + Assert.AreEqual(0, result.PluginServices.Count()); + Assert.AreEqual(typeName, result.PluginType.Name); + } + + [TestMethod] + public void ProvideActivationContext_WithActivatedMethod_Works() + { + var assemblyShim = this.mockRepository.Create(); + var contract = GetContract(); + var pluginAttribute = GetPluginAttributeForContract(contract); + + // Factory method + var factoryMethodName = "This_Is_The_Factory_Method"; + var factoryMethod = TestableMethodInfoBuilder.New() + .WithName(factoryMethodName) + .WithAttribute(TestableAttributeBuilder.New() + .WithAttributeType(typeof(Prise.Plugin.PluginFactoryAttribute)).Build()) + .Build(); + + // Activated method + var activatedMethodName = "This_Is_The_Activation_Method"; + var activatedMethod = TestableMethodInfoBuilder.New() + .WithName(activatedMethodName) + .WithAttribute(TestableAttributeBuilder.New() + .WithAttributeType(typeof(Prise.Plugin.PluginActivatedAttribute)).Build()) + .Build(); + + var typeName = "MyTestType"; + var testableType = TestableTypeBuilder.New() + .WithCustomAttributes(pluginAttribute) + .WithName(typeName) + .WithNamespace("Test.Type") + .WithMethods(new[] { factoryMethod, activatedMethod }) + .Build(); + + // NO bootstrapper + // NO services + + assemblyShim.Setup(a => a.Types).Returns(new[] { testableType }); + + var sut = new DefaultPluginActivationContextProvider(); + var result = sut.ProvideActivationContext(testableType, assemblyShim.Object); + + Assert.IsNotNull(result); + Assert.IsNotNull(result.PluginActivatedMethod); + Assert.AreEqual(activatedMethodName, result.PluginActivatedMethod.Name); + Assert.IsNotNull(result.PluginFactoryMethod); + Assert.AreEqual(factoryMethodName, result.PluginFactoryMethod.Name); + Assert.AreEqual(0, result.PluginServices.Count()); + Assert.AreEqual(typeName, result.PluginType.Name); + } + + [TestMethod] + public void ProvideActivationContext_WithPluginServices_Works() + { + var assemblyShim = this.mockRepository.Create(); + var contract = GetContract(); + var pluginAttribute = GetPluginAttributeForContract(contract); + + // Factory method + var factoryMethodName = "This_Is_The_Factory_Method"; + var factoryMethod = TestableMethodInfoBuilder.New() + .WithName(factoryMethodName) + .WithAttribute(TestableAttributeBuilder.New() + .WithAttributeType(typeof(Prise.Plugin.PluginFactoryAttribute)).Build()) + .Build(); + + // Activated method + var activatedMethodName = "This_Is_The_Activation_Method"; + var activatedMethod = TestableMethodInfoBuilder.New() + .WithName(activatedMethodName) + .WithAttribute(TestableAttributeBuilder.New() + .WithAttributeType(typeof(Prise.Plugin.PluginActivatedAttribute)).Build()) + .Build(); + + + var serviceTypeName1 = "IMyService1"; + var serviceType1 = TestableTypeBuilder.New() + .WithName(serviceTypeName1) + .WithNamespace("Test.Type") + .Build(); + + var pluginService1 = "pluginService"; + var serviceField1 = TestableFieldBuilder.New() + .WithName(pluginService1) + .WithAttribute(TestableAttributeBuilder.New() + .WithAttributeType(typeof(Prise.Plugin.PluginServiceAttribute)) + .WithNamedAgrument("ServiceType", serviceType1) + .WithNamedAgrument("ProvidedBy", ProvidedBy.Plugin) + .Build()) + .Build(); + + var proxyTypeName = "IProxyType"; + var proxyType = TestableTypeBuilder.New() + .WithName(proxyTypeName) + .WithNamespace("Test.Type") + .Build(); + + var pluginService2 = "hostService"; + var serviceField2 = TestableFieldBuilder.New() + .WithName(pluginService2) + .WithAttribute(TestableAttributeBuilder.New() + .WithAttributeType(typeof(Prise.Plugin.PluginServiceAttribute)) + .WithNamedAgrument("ServiceType", serviceType1) + .WithNamedAgrument("ProvidedBy", ProvidedBy.Host) + .WithNamedAgrument("ProxyType", proxyType) + .Build()) + .Build(); + + var typeName = "MyTestType"; + var testableType = TestableTypeBuilder.New() + .WithCustomAttributes(pluginAttribute) + .WithName(typeName) + .WithNamespace("Test.Type") + .WithMethods(new[] { factoryMethod, activatedMethod }) + .WithFields(new[] { serviceField1, serviceField2 }) + .Build(); + + // NO bootstrapper + + assemblyShim.Setup(a => a.Types).Returns(new[] { testableType }); + + var sut = new DefaultPluginActivationContextProvider(); + var result = sut.ProvideActivationContext(testableType, assemblyShim.Object); + + Assert.IsNotNull(result); + Assert.IsNotNull(result.PluginActivatedMethod); + Assert.AreEqual(activatedMethodName, result.PluginActivatedMethod.Name); + Assert.IsNotNull(result.PluginFactoryMethod); + Assert.AreEqual(factoryMethodName, result.PluginFactoryMethod.Name); + Assert.AreEqual(2, result.PluginServices.Count()); + Assert.AreEqual(pluginService1, result.PluginServices.ElementAt(0).FieldName); + Assert.AreEqual(pluginService2, result.PluginServices.ElementAt(1).FieldName); + Assert.AreEqual(ProvidedBy.Plugin, result.PluginServices.ElementAt(0).ProvidedBy); + Assert.AreEqual(ProvidedBy.Host, result.PluginServices.ElementAt(1).ProvidedBy); + Assert.IsNull(result.PluginServices.ElementAt(0).ProxyType); + Assert.IsNotNull(result.PluginServices.ElementAt(1).ProxyType); + Assert.AreEqual(proxyTypeName, result.PluginServices.ElementAt(1).ProxyType.Name); + Assert.AreEqual(serviceTypeName1, result.PluginServices.ElementAt(0).ServiceType.Name); + Assert.AreEqual(serviceTypeName1, result.PluginServices.ElementAt(1).ServiceType.Name); + Assert.AreEqual(typeName, result.PluginType.Name); + } + + [TestMethod] + public void ProvideActivationContext_WithBootstrapper_Works() + { + var assemblyShim = this.mockRepository.Create(); + var contract = GetContract(); + var pluginAttribute = GetPluginAttributeForContract(contract); + + var serviceTypeName = "IMyService1"; + var serviceType = TestableTypeBuilder.New() + .WithName(serviceTypeName) + .WithNamespace("Test.Type") + .Build(); + + var proxyTypeName = "BootstrapperService"; + var proxyType = TestableTypeBuilder.New() + .WithName(proxyTypeName) + .WithNamespace("Test.Type") + .Build(); + + var bootstrapperServiceFieldName = "bootstrapperService"; + var bootstrapperServiceField = TestableFieldBuilder.New() + .WithName(bootstrapperServiceFieldName) + .WithAttribute(TestableAttributeBuilder.New() + .WithAttributeType(typeof(Prise.Plugin.BootstrapperServiceAttribute)) + .WithNamedAgrument("ServiceType", serviceType) + .WithNamedAgrument("ProxyType", proxyType) + .Build()) + .Build(); + + var typeName = "MyTestType"; + var testableType = TestableTypeBuilder.New() + .WithCustomAttributes(pluginAttribute) + .WithName(typeName) + .WithNamespace("Test.Type") + .Build(); + + var bootstrapperAttribute = TestableAttributeBuilder.New() + .WithAttributeType(typeof(Prise.Plugin.PluginBootstrapperAttribute)) + .WithNamedAgrument("PluginType", testableType) + .Build(); + + var bootstrapperName = "MyTestTypeBootstrapper"; + var bootstrapperType = TestableTypeBuilder.New() + .WithCustomAttributes(bootstrapperAttribute) + .WithName(bootstrapperName) + .WithNamespace("Test.Type") + .WithFields(new[] { bootstrapperServiceField }) + .Build(); + + assemblyShim.Setup(a => a.Types).Returns(new[] { testableType, bootstrapperType }); + + var sut = new DefaultPluginActivationContextProvider(); + var result = sut.ProvideActivationContext(testableType, assemblyShim.Object); + + Assert.IsNotNull(result); + Assert.IsNull(result.PluginActivatedMethod); + Assert.IsNull(result.PluginFactoryMethod); + Assert.AreEqual(0, result.PluginServices.Count()); + Assert.AreEqual(bootstrapperServiceFieldName, result.BootstrapperServices.ElementAt(0).FieldName); + Assert.AreEqual(proxyTypeName, result.BootstrapperServices.ElementAt(0).ProxyType.Name); + Assert.AreEqual(serviceTypeName, result.BootstrapperServices.ElementAt(0).ServiceType.Name); + Assert.AreEqual(typeName, result.PluginType.Name); + Assert.AreEqual(bootstrapperName, result.PluginBootstrapperType.Name); + } + } +} \ No newline at end of file diff --git a/Vendor/Prise.Tests/Assemblies/Newtonsoft.Json.dll b/Vendor/Prise.Tests/Assemblies/Newtonsoft.Json.dll new file mode 100644 index 0000000..5f2336e Binary files /dev/null and b/Vendor/Prise.Tests/Assemblies/Newtonsoft.Json.dll differ diff --git a/Vendor/Prise.Tests/Assemblies/Prise.Tests.dll b/Vendor/Prise.Tests/Assemblies/Prise.Tests.dll new file mode 100644 index 0000000..f568fbe Binary files /dev/null and b/Vendor/Prise.Tests/Assemblies/Prise.Tests.dll differ diff --git a/Vendor/Prise.Tests/Assemblies/en-GB/Newtonsoft.Json.dll b/Vendor/Prise.Tests/Assemblies/en-GB/Newtonsoft.Json.dll new file mode 100644 index 0000000..5f2336e Binary files /dev/null and b/Vendor/Prise.Tests/Assemblies/en-GB/Newtonsoft.Json.dll differ diff --git a/Vendor/Prise.Tests/Assemblies/libsos.so b/Vendor/Prise.Tests/Assemblies/libsos.so new file mode 100644 index 0000000..187c67c Binary files /dev/null and b/Vendor/Prise.Tests/Assemblies/libsos.so differ diff --git a/Vendor/Prise.Tests/AssemblyLoading/DefaultAssemblyLoadContextTests/Base.cs b/Vendor/Prise.Tests/AssemblyLoading/DefaultAssemblyLoadContextTests/Base.cs new file mode 100644 index 0000000..1ae26c8 --- /dev/null +++ b/Vendor/Prise.Tests/AssemblyLoading/DefaultAssemblyLoadContextTests/Base.cs @@ -0,0 +1,129 @@ +using Moq; +using Prise.AssemblyLoading; + +using Prise.Tests.Plugins; +using System; +using System.IO; +using System.Reflection; +using System.Runtime.Loader; +using System.Threading.Tasks; + +namespace Prise.Tests.AssemblyLoading.DefaultAssemblyLoadContextTests +{ + public class AssemblyLoadContextWithLoadedPluginTestContext + { + public string PluginAssemblyPath { get; set; } + public string InitialPluginLoadDirectory { get; set; } + public string NewtonsoftAssemblyPath { get; set; } + public AssemblyName NewtonsoftAssemblyName { get; set; } + public Assembly NewtonsoftAssembly { get; set; } + public IPluginLoadContext PluginLoadContext { get; set; } + public TestContext TestContext { get; set; } + + public IAssemblyLoadContext Sut() => this.TestContext.Sut(); + + public Mock GetMock() + where M : class + { + return this.TestContext.GetMock(); + } + } + + public class TestWithLoadedPluginBase : Base + { + protected async Task SetupLoadedPluginTextContext(Action configure = null) + { + var testContext = SetupAssemblyLoadContext(); + var loadContext = testContext.Sut(); + var fileSystemUtility = testContext.GetMock(); + var assemblyLoadStrategy = testContext.GetMock(); + var pluginDependencyContext = testContext.GetMock(); + var pluginDependencyProvider = testContext.GetMock(); + + var pluginAssemblyPath = Path.Combine(GetPathToAssemblies(), "Prise.Tests.dll"); + var initialPluginLoadDirectory = Path.GetDirectoryName(pluginAssemblyPath); + + var newtonsoftAssemblyPath = Path.Combine(GetPathToAssemblies(), "Newtonsoft.Json.dll"); + var newtonsoftAssembly = Assembly.LoadFile(newtonsoftAssemblyPath); + var newtonsoftAssemblyName = AssemblyLoadContext.GetAssemblyName(newtonsoftAssemblyPath); + var assemblyStream = File.OpenRead(pluginAssemblyPath); + + var pluginLoadContext = GetPluginLoadContext(pluginAssemblyPath, configure); + + fileSystemUtility.Setup(f => f.EnsureFileExists(pluginAssemblyPath)).Returns(pluginAssemblyPath); + fileSystemUtility.Setup(f => f.ReadFileFromDisk(pluginAssemblyPath)).ReturnsAsync(assemblyStream); + pluginDependencyProvider.Setup(p => p.FromPluginLoadContext(pluginLoadContext)).ReturnsAsync(pluginDependencyContext.Object); + + // This must be invoked before anything else can be tested + await loadContext.LoadPluginAssembly(pluginLoadContext); + + return new AssemblyLoadContextWithLoadedPluginTestContext + { + TestContext = testContext, + InitialPluginLoadDirectory = initialPluginLoadDirectory, + PluginAssemblyPath = pluginAssemblyPath, + PluginLoadContext = pluginLoadContext, + NewtonsoftAssembly = newtonsoftAssembly, + NewtonsoftAssemblyName = newtonsoftAssemblyName, + NewtonsoftAssemblyPath = newtonsoftAssemblyPath, + }; + } + } + public class Base : TestBase + { + protected T InvokeProtectedMethodOnLoadContextAndGetResult(IAssemblyLoadContext loadContext, string methodName, params object[] args) + { + return (T)loadContext + .GetType() + .GetMethod(methodName, BindingFlags.Instance | BindingFlags.NonPublic) + .Invoke(loadContext, args); + } + + protected IPluginLoadContext GetPluginLoadContext(string pluginAssemblyPath, Action configure = null) + { + var pluginLoadContext = new PluginLoadContext(pluginAssemblyPath, GetContractType(), "netcoreapp3.1"); + configure?.Invoke(pluginLoadContext); + return pluginLoadContext; + } + + protected Type GetContractType() + { + return TestableTypeBuilder.New() + .WithName("IMyTestType") + .WithNamespace("Test.Type") + .Build(); + } + + protected TestContext SetupAssemblyLoadContext() + { + var nativeUnloader = this.mockRepository.Create(); + var pluginDependencyResolver = this.mockRepository.Create(); + var assemblyLoadStrategy = this.mockRepository.Create(); + var pluginDependencyContext = this.mockRepository.Create(); + var resolver = this.mockRepository.Create(); + var fileSystemUtility = this.mockRepository.Create(); + var runtimeDefaultAssemblyLoadContext = this.mockRepository.Create(); + var pluginDependencyContextProvider = this.mockRepository.Create(); + + var loadContext = new DefaultAssemblyLoadContext( + () => nativeUnloader.Object, + () => pluginDependencyResolver.Object, + () => assemblyLoadStrategy.Object, + (s) => resolver.Object, + () => fileSystemUtility.Object, + () => runtimeDefaultAssemblyLoadContext.Object, + () => pluginDependencyContextProvider.Object); + + return new TestContext(loadContext, + nativeUnloader, + pluginDependencyResolver, + assemblyLoadStrategy, + pluginDependencyContext, + resolver, + fileSystemUtility, + runtimeDefaultAssemblyLoadContext, + pluginDependencyContextProvider + ); + } + } +} \ No newline at end of file diff --git a/Vendor/Prise.Tests/AssemblyLoading/DefaultAssemblyLoadContextTests/DefaultAssemblyLoadContextTests_Ctor.cs b/Vendor/Prise.Tests/AssemblyLoading/DefaultAssemblyLoadContextTests/DefaultAssemblyLoadContextTests_Ctor.cs new file mode 100644 index 0000000..e2479d2 --- /dev/null +++ b/Vendor/Prise.Tests/AssemblyLoading/DefaultAssemblyLoadContextTests/DefaultAssemblyLoadContextTests_Ctor.cs @@ -0,0 +1,67 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Prise.AssemblyLoading; +using System; + +namespace Prise.Tests.AssemblyLoading.DefaultAssemblyLoadContextTests +{ + [TestClass] + public class DefaultAssemblyLoadContextTests_Ctor : Base + { + [TestMethod] + public void Ctor_Throws_ArgumentNullException_nativeAssemblyUnloaderFactory() + { + var exception = Assert.ThrowsException(() => new DefaultAssemblyLoadContext(null, null, null, null, null, null, null)); + exception.Message.Contains("nativeAssemblyUnloaderFactory"); + } + + [TestMethod] + public void Ctor_Throws_ArgumentNullException_pluginDependencyResolverFactory() + { + var exception = Assert.ThrowsException(() => new DefaultAssemblyLoadContext(() => null, null, null, null, null, null, null)); + exception.Message.Contains("pluginDependencyResolverFactory"); + } + + [TestMethod] + public void Ctor_Throws_ArgumentNullException_assemblyLoadStrategyFactory() + { + var exception = Assert.ThrowsException(() => new DefaultAssemblyLoadContext(() => null, () => null, null, null, null, null, null)); + exception.Message.Contains("assemblyLoadStrategyFactory"); + } + + [TestMethod] + public void Ctor_Throws_ArgumentNullException_assemblyDependencyResolverFactory() + { + var exception = Assert.ThrowsException(() => new DefaultAssemblyLoadContext(() => null, () => null, () => null, null, null, null, null)); + exception.Message.Contains("assemblyDependencyResolverFactory"); + } + + + [TestMethod] + public void Ctor_Throws_ArgumentNullException_fileSystemUtilitiesFactory() + { + var exception = Assert.ThrowsException(() => new DefaultAssemblyLoadContext(() => null, () => null, () => null, (c) => null, null, null, null)); + exception.Message.Contains("fileSystemUtilitiesFactory"); + } + + [TestMethod] + public void Ctor_Throws_ArgumentNullException_runtimeDefaultAssemblyLoadContextFactory() + { + var exception = Assert.ThrowsException(() => new DefaultAssemblyLoadContext(() => null, () => null, () => null, (c) => null, () => null, null, null)); + exception.Message.Contains("runtimeDefaultAssemblyLoadContextFactory"); + } + + + [TestMethod] + public void Ctor_Throws_ArgumentNullException_pluginDependencyContextProviderFactory() + { + var exception = Assert.ThrowsException(() => new DefaultAssemblyLoadContext(() => null, () => null, () => null, (c) => null, () => null, () => null, null)); + exception.Message.Contains("pluginDependencyContextProviderFactory"); + } + + [TestMethod] + public void Ctor_Works() + { + Assert.IsNotNull(new DefaultAssemblyLoadContext(() => null, () => null, () => null, (c) => null, () => null, () => null, () => null)); + } + } +} \ No newline at end of file diff --git a/Vendor/Prise.Tests/AssemblyLoading/DefaultAssemblyLoadContextTests/DefaultAssemblyLoadContextTests_Load.cs b/Vendor/Prise.Tests/AssemblyLoading/DefaultAssemblyLoadContextTests/DefaultAssemblyLoadContextTests_Load.cs new file mode 100644 index 0000000..43a08cd --- /dev/null +++ b/Vendor/Prise.Tests/AssemblyLoading/DefaultAssemblyLoadContextTests/DefaultAssemblyLoadContextTests_Load.cs @@ -0,0 +1,64 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Moq; +using Prise.AssemblyLoading; + +using Prise.Tests.Plugins; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Runtime.Loader; +using System.Threading.Tasks; + +namespace Prise.Tests.AssemblyLoading.DefaultAssemblyLoadContextTests +{ + [TestClass] + public class DefaultAssemblyLoadContextTests_Load : TestWithLoadedPluginBase + { + [TestMethod] + public async Task Disposing_Prevents_Load() + { + var testContext = SetupAssemblyLoadContext(); + var loadContext = testContext.Sut(); + + var assembly = this.GetType().Assembly; + var assemblyName = AssemblyLoadContext.GetAssemblyName(assembly.Location); + + loadContext.Dispose(); + var result = loadContext.GetType().GetMethod("Load", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(loadContext, new[] { assemblyName }) as Assembly; + Assert.IsNull(result); + } + + [TestMethod] + public async Task Load_Works() + { + var testContext = await SetupLoadedPluginTextContext(); + var loadContext = testContext.Sut(); + var assemblyLoadStrategy = testContext.GetMock(); + var initialPluginLoadDirectory = testContext.InitialPluginLoadDirectory; + var pluginLoadContext = testContext.PluginLoadContext; + var pluginDependencyContext = testContext.GetMock(); + var newtonsoftAssemblyPath = Path.Combine(GetPathToAssemblies(), "Newtonsoft.Json.dll"); + var newtonsoftAssembly = Assembly.LoadFile(newtonsoftAssemblyPath); + var newtonsoftAssemblyName = AssemblyLoadContext.GetAssemblyName(newtonsoftAssemblyPath); + + assemblyLoadStrategy.Setup(a => a.LoadAssembly(initialPluginLoadDirectory, newtonsoftAssemblyName, pluginDependencyContext.Object, + It.IsAny>>(), + It.IsAny>>(), + It.IsAny>>())) + .Returns(new AssemblyFromStrategy + { + Assembly = newtonsoftAssembly, + CanBeReleased = true + }); + + var result = InvokeProtectedMethodOnLoadContextAndGetResult( + loadContext, + "Load", + new object[] { newtonsoftAssemblyName }); + + Assert.IsNotNull(result); + } + } +} \ No newline at end of file diff --git a/Vendor/Prise.Tests/AssemblyLoading/DefaultAssemblyLoadContextTests/DefaultAssemblyLoadContextTests_LoadFromDefaultContext.cs b/Vendor/Prise.Tests/AssemblyLoading/DefaultAssemblyLoadContextTests/DefaultAssemblyLoadContextTests_LoadFromDefaultContext.cs new file mode 100644 index 0000000..2d37764 --- /dev/null +++ b/Vendor/Prise.Tests/AssemblyLoading/DefaultAssemblyLoadContextTests/DefaultAssemblyLoadContextTests_LoadFromDefaultContext.cs @@ -0,0 +1,190 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Moq; +using Prise.AssemblyLoading; + +using Prise.Tests.Plugins; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Runtime.Loader; +using System.Threading.Tasks; + +namespace Prise.Tests.AssemblyLoading.DefaultAssemblyLoadContextTests +{ + [TestClass] + public class DefaultAssemblyLoadContextTests_LoadFromDefaultContext : TestWithLoadedPluginBase + { + [TestMethod] + public async Task LoadFromDefaultContext_Returns_Assembly() + { + var testContext = await SetupLoadedPluginTextContext(); + var loadContext = testContext.Sut(); + var fileSystemUtility = testContext.GetMock(); + var runtimeDefaultAssemblyLoadContext = testContext.GetMock(); + var initialPluginLoadDirectory = testContext.InitialPluginLoadDirectory; + var pluginLoadContext = testContext.PluginLoadContext; + var newtonsoftAssemblyName = testContext.NewtonsoftAssemblyName; + var newtonsoftAssembly = testContext.NewtonsoftAssembly; + + runtimeDefaultAssemblyLoadContext.Setup(r => r.LoadFromDefaultContext(newtonsoftAssemblyName)).Returns(new RuntimeAssemblyShim(newtonsoftAssembly, RuntimeLoadFlag.FromRequestedVersion)); + + var result = InvokeProtectedMethodOnLoadContextAndGetResult>( + loadContext, + "LoadFromDefaultContext", + new object[] { initialPluginLoadDirectory, newtonsoftAssemblyName }); + + Assert.IsNotNull(result); + Assert.IsFalse(result.CanProceed); + Assert.AreEqual(RuntimeLoadFlag.FromRequestedVersion, result.Value.RuntimeLoadFlag); + Assert.AreEqual(newtonsoftAssemblyName.Name, result.Value.Assembly.GetName().Name); + } + + [TestMethod] + public async Task LoadFromDefaultContext_Returns_Assembly_FromRuntimeVersion() + { + var testContext = await SetupLoadedPluginTextContext(); + var loadContext = testContext.Sut(); + var fileSystemUtility = testContext.GetMock(); + var runtimeDefaultAssemblyLoadContext = testContext.GetMock(); + var initialPluginLoadDirectory = testContext.InitialPluginLoadDirectory; + var pluginLoadContext = testContext.PluginLoadContext; + var newtonsoftAssemblyName = testContext.NewtonsoftAssemblyName; + var newtonsoftAssembly = testContext.NewtonsoftAssembly; + + runtimeDefaultAssemblyLoadContext.Setup(r => r.LoadFromDefaultContext(newtonsoftAssemblyName)).Returns(new RuntimeAssemblyShim(newtonsoftAssembly, RuntimeLoadFlag.FromRuntimeVersion)); + + var result = InvokeProtectedMethodOnLoadContextAndGetResult>( + loadContext, + "LoadFromDefaultContext", + new object[] { initialPluginLoadDirectory, newtonsoftAssemblyName }); + + Assert.IsNotNull(result); + Assert.IsFalse(result.CanProceed); + Assert.AreEqual(RuntimeLoadFlag.FromRuntimeVersion, result.Value.RuntimeLoadFlag); + Assert.AreEqual(newtonsoftAssemblyName.Name, result.Value.Assembly.GetName().Name); + } + + [TestMethod] + public async Task LoadFromDefaultContext_Throws_AssemblyLoadingException_When_FileNotFoundException_And_AllowDowngrade_False() + { + var testContext = await SetupLoadedPluginTextContext(); + var loadContext = testContext.Sut(); + var fileSystemUtility = testContext.GetMock(); + var runtimeDefaultAssemblyLoadContext = testContext.GetMock(); + var pluginDependencyContext = testContext.GetMock(); + var initialPluginLoadDirectory = testContext.InitialPluginLoadDirectory; + var pluginLoadContext = testContext.PluginLoadContext; + var newtonsoftAssemblyName = testContext.NewtonsoftAssemblyName; + var newtonsoftAssembly = testContext.NewtonsoftAssembly; + + runtimeDefaultAssemblyLoadContext.Setup(r => r.LoadFromDefaultContext(newtonsoftAssemblyName)).Throws(); + + pluginDependencyContext.SetupGet(p => p.HostDependencies).Returns(new[]{ + new HostDependency + { + DependencyName = newtonsoftAssemblyName, + AllowDowngrade = false + } + }); + + var exception = Assert + .ThrowsException(() => + InvokeProtectedMethodOnLoadContextAndGetResult>( + loadContext, + "LoadFromDefaultContext", + new object[] { initialPluginLoadDirectory, newtonsoftAssemblyName }) + ); + Assert.IsInstanceOfType(exception.InnerException, typeof(AssemblyLoadingException)); + } + + [TestMethod] + public async Task LoadFromDefaultContext_Returns_Proceed_When_FileNotFoundException_And_AllowDowngrade_True() + { + var testContext = await SetupLoadedPluginTextContext(); + var loadContext = testContext.Sut(); + var fileSystemUtility = testContext.GetMock(); + var runtimeDefaultAssemblyLoadContext = testContext.GetMock(); + var pluginDependencyContext = testContext.GetMock(); + var initialPluginLoadDirectory = testContext.InitialPluginLoadDirectory; + var pluginLoadContext = testContext.PluginLoadContext; + var newtonsoftAssemblyName = testContext.NewtonsoftAssemblyName; + var newtonsoftAssembly = testContext.NewtonsoftAssembly; + + runtimeDefaultAssemblyLoadContext.Setup(r => r.LoadFromDefaultContext(newtonsoftAssemblyName)).Returns((RuntimeAssemblyShim)null); + + pluginDependencyContext.SetupGet(p => p.HostDependencies).Returns(new[]{ + new HostDependency + { + DependencyName = newtonsoftAssemblyName, + AllowDowngrade = true + } + }); + + var result = InvokeProtectedMethodOnLoadContextAndGetResult>( + loadContext, + "LoadFromDefaultContext", + new object[] { initialPluginLoadDirectory, newtonsoftAssemblyName }); + + Assert.IsNull(result.Value); + Assert.IsTrue(result.CanProceed); + } + + [TestMethod] + public async Task LoadFromDefaultContext_Returns_Proceed_When_Assembly_Null() + { + var testContext = await SetupLoadedPluginTextContext(); + var loadContext = testContext.Sut(); + var fileSystemUtility = testContext.GetMock(); + var runtimeDefaultAssemblyLoadContext = testContext.GetMock(); + var pluginDependencyContext = testContext.GetMock(); + var initialPluginLoadDirectory = testContext.InitialPluginLoadDirectory; + var pluginLoadContext = testContext.PluginLoadContext; + var newtonsoftAssemblyName = testContext.NewtonsoftAssemblyName; + var newtonsoftAssembly = testContext.NewtonsoftAssembly; + + runtimeDefaultAssemblyLoadContext.Setup(r => r.LoadFromDefaultContext(newtonsoftAssemblyName)).Returns((RuntimeAssemblyShim)null); + pluginDependencyContext.SetupGet(p => p.HostDependencies).Returns(Enumerable.Empty()); + + var result = InvokeProtectedMethodOnLoadContextAndGetResult>( + loadContext, + "LoadFromDefaultContext", + new object[] { initialPluginLoadDirectory, newtonsoftAssemblyName }); + + Assert.IsNull(result.Value); + Assert.IsTrue(result.CanProceed); + } + + [TestMethod] + public async Task LoadFromDefaultContext_Returns_Proceed_When_HostAssembly_Not_Found() + { + var testContext = await SetupLoadedPluginTextContext(); + var loadContext = testContext.Sut(); + var fileSystemUtility = testContext.GetMock(); + var runtimeDefaultAssemblyLoadContext = testContext.GetMock(); + var pluginDependencyContext = testContext.GetMock(); + var initialPluginLoadDirectory = testContext.InitialPluginLoadDirectory; + var pluginLoadContext = testContext.PluginLoadContext; + var newtonsoftAssemblyName = testContext.NewtonsoftAssemblyName; + var newtonsoftAssembly = testContext.NewtonsoftAssembly; + + runtimeDefaultAssemblyLoadContext.Setup(r => r.LoadFromDefaultContext(newtonsoftAssemblyName)).Returns((RuntimeAssemblyShim)null); + + pluginDependencyContext.SetupGet(p => p.HostDependencies).Returns(new[]{ + new HostDependency + { + DependencyName = new AssemblyName() + } + }); + + var result = InvokeProtectedMethodOnLoadContextAndGetResult>( + loadContext, + "LoadFromDefaultContext", + new object[] { initialPluginLoadDirectory, newtonsoftAssemblyName }); + + Assert.IsNull(result.Value); + Assert.IsTrue(result.CanProceed); + } + } +} \ No newline at end of file diff --git a/Vendor/Prise.Tests/AssemblyLoading/DefaultAssemblyLoadContextTests/DefaultAssemblyLoadContextTests_LoadFromDependencyContext.cs b/Vendor/Prise.Tests/AssemblyLoading/DefaultAssemblyLoadContextTests/DefaultAssemblyLoadContextTests_LoadFromDependencyContext.cs new file mode 100644 index 0000000..b83b0f7 --- /dev/null +++ b/Vendor/Prise.Tests/AssemblyLoading/DefaultAssemblyLoadContextTests/DefaultAssemblyLoadContextTests_LoadFromDependencyContext.cs @@ -0,0 +1,250 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Moq; +using Prise.AssemblyLoading; + +using Prise.Tests.Plugins; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Runtime.Loader; +using System.Threading.Tasks; +namespace Prise.Tests.AssemblyLoading.DefaultAssemblyLoadContextTests +{ + [TestClass] + public class DefaultAssemblyLoadContextTests_LoadFromDependencyContext : TestWithLoadedPluginBase + { + [TestMethod] + public async Task LoadFromDependencyContext_FromResolver_Works() + { + var testContext = await SetupLoadedPluginTextContext(); + var loadContext = testContext.Sut(); + var fileSystemUtility = testContext.GetMock(); + var runtimeDefaultAssemblyLoadContext = testContext.GetMock(); + var initialPluginLoadDirectory = testContext.InitialPluginLoadDirectory; + var pluginLoadContext = testContext.PluginLoadContext; + var newtonsoftAssemblyName = testContext.NewtonsoftAssemblyName; + var newtonsoftAssembly = testContext.NewtonsoftAssembly; + var newtonsoftAssemblyPath = testContext.NewtonsoftAssemblyPath; + var resolver = testContext.GetMock(); + + resolver.Setup(r => r.ResolveAssemblyToPath(newtonsoftAssemblyName)).Returns(newtonsoftAssemblyPath); + fileSystemUtility.Setup(r => r.DoesFileExist(newtonsoftAssemblyPath)).Returns(true); + + var result = InvokeProtectedMethodOnLoadContextAndGetResult>( + loadContext, + "LoadFromDependencyContext", + new object[] { initialPluginLoadDirectory, newtonsoftAssemblyName }); + + Assert.IsNotNull(result); + Assert.AreEqual(newtonsoftAssemblyName.Name, result.Value.Assembly.GetName().Name); + } + + [TestMethod] + public async Task LoadFromDependencyContext_FromResourceAssembly_Returns_Null() + { + var testContext = await SetupLoadedPluginTextContext(); + var loadContext = testContext.Sut(); + var fileSystemUtility = testContext.GetMock(); + var runtimeDefaultAssemblyLoadContext = testContext.GetMock(); + var initialPluginLoadDirectory = testContext.InitialPluginLoadDirectory; + var pluginLoadContext = testContext.PluginLoadContext; + var newtonsoftAssemblyName = testContext.NewtonsoftAssemblyName; + var newtonsoftAssembly = testContext.NewtonsoftAssembly; + var newtonsoftAssemblyPath = testContext.NewtonsoftAssemblyPath; + var resolver = testContext.GetMock(); + var pluginDependencyContext = testContext.GetMock(); + + // Configure as resource assembly + newtonsoftAssemblyName.CultureName = "en-GB"; + + resolver.Setup(r => r.ResolveAssemblyToPath(newtonsoftAssemblyName)).Returns(String.Empty); + pluginDependencyContext.SetupGet(p => p.PluginResourceDependencies).Returns(new List());// return empty list + + var result = InvokeProtectedMethodOnLoadContextAndGetResult>( + loadContext, + "LoadFromDependencyContext", + new object[] { initialPluginLoadDirectory, newtonsoftAssemblyName }); + + Assert.IsNotNull(result); + Assert.IsNull(result.Value); + Assert.IsFalse(result.CanProceed); + } + + [TestMethod] + public async Task LoadFromDependencyContext_FromResourceAssembly_Returns_Assembly() + { + var testContext = await SetupLoadedPluginTextContext(); + var loadContext = testContext.Sut(); + var fileSystemUtility = testContext.GetMock(); + var runtimeDefaultAssemblyLoadContext = testContext.GetMock(); + var initialPluginLoadDirectory = testContext.InitialPluginLoadDirectory; + var pluginLoadContext = testContext.PluginLoadContext; + var newtonsoftAssemblyName = testContext.NewtonsoftAssemblyName; + var newtonsoftAssembly = testContext.NewtonsoftAssembly; + var newtonsoftAssemblyPath = testContext.NewtonsoftAssemblyPath; + var resolver = testContext.GetMock(); + var pluginDependencyContext = testContext.GetMock(); + + // Configure as resource assembly + var culture = "en-GB"; + newtonsoftAssemblyName.CultureName = culture; + + resolver.Setup(r => r.ResolveAssemblyToPath(newtonsoftAssemblyName)).Returns(String.Empty); + pluginDependencyContext.SetupGet(p => p.PluginResourceDependencies).Returns(new[]{ + new PluginResourceDependency + { + Path = GetPathToAssemblies() + }, + new PluginResourceDependency + { + Path = "/test" + } + }); + + fileSystemUtility.Setup(r => r.DoesFileExist($"{GetPathToAssemblies()}/{culture}/{newtonsoftAssemblyName.Name}.dll")).Returns(true); + + var result = InvokeProtectedMethodOnLoadContextAndGetResult>( + loadContext, + "LoadFromDependencyContext", + new object[] { initialPluginLoadDirectory, newtonsoftAssemblyName }); + + Assert.IsNotNull(result); + Assert.AreEqual(newtonsoftAssemblyName.Name, result.Value.Assembly.GetName().Name); + } + + [TestMethod] + public async Task LoadFromDependencyContext_FromPluginDependency_Returns_Assembly() + { + var testContext = await SetupLoadedPluginTextContext(); + var loadContext = testContext.Sut(); + var fileSystemUtility = testContext.GetMock(); + var runtimeDefaultAssemblyLoadContext = testContext.GetMock(); + var initialPluginLoadDirectory = testContext.InitialPluginLoadDirectory; + var pluginLoadContext = testContext.PluginLoadContext; + var newtonsoftAssemblyName = testContext.NewtonsoftAssemblyName; + var newtonsoftAssembly = testContext.NewtonsoftAssembly; + var newtonsoftAssemblyPath = testContext.NewtonsoftAssemblyPath; + var resolver = testContext.GetMock(); + var pluginDependencyContext = testContext.GetMock(); + var pluginDependencyResolver = testContext.GetMock(); + + var newtonsoftAssemblyStream = File.OpenRead(newtonsoftAssemblyPath); + + // Skip the resolver + resolver.Setup(r => r.ResolveAssemblyToPath(newtonsoftAssemblyName)).Returns(String.Empty); + + // Skip resources assembly + // newtonsoftAssemblyName does not contain a culture + + var pluginDependency = new PluginDependency + { + DependencyNameWithoutExtension = newtonsoftAssemblyName.Name + }; + + var additionalProbingPaths = Enumerable.Empty(); + pluginDependencyContext.SetupGet(p => p.AdditionalProbingPaths).Returns(additionalProbingPaths); + pluginDependencyContext.SetupGet(p => p.PluginDependencies).Returns(new[]{ + new PluginDependency + { + DependencyNameWithoutExtension = "not-the-droid-im-looking-for" + }, + pluginDependency + }); + + pluginDependencyResolver.Setup(r => r.ResolvePluginDependencyToPath(initialPluginLoadDirectory, pluginDependency, additionalProbingPaths)).Returns(newtonsoftAssemblyStream); + + var result = InvokeProtectedMethodOnLoadContextAndGetResult>( + loadContext, + "LoadFromDependencyContext", + new object[] { initialPluginLoadDirectory, newtonsoftAssemblyName }); + + Assert.IsNotNull(result); + Assert.AreEqual(newtonsoftAssemblyName.Name, result.Value.Assembly.GetName().Name); + } + + [TestMethod] + public async Task LoadFromDependencyContext_FromLocal_Returns_Assembly() + { + var testContext = await SetupLoadedPluginTextContext(); + var loadContext = testContext.Sut(); + var fileSystemUtility = testContext.GetMock(); + var runtimeDefaultAssemblyLoadContext = testContext.GetMock(); + var initialPluginLoadDirectory = testContext.InitialPluginLoadDirectory; + var pluginLoadContext = testContext.PluginLoadContext; + var newtonsoftAssemblyName = testContext.NewtonsoftAssemblyName; + var newtonsoftAssembly = testContext.NewtonsoftAssembly; + var newtonsoftAssemblyPath = testContext.NewtonsoftAssemblyPath; + var resolver = testContext.GetMock(); + var pluginDependencyContext = testContext.GetMock(); + var pluginDependencyResolver = testContext.GetMock(); + + // Skip the resolver + resolver.Setup(r => r.ResolveAssemblyToPath(newtonsoftAssemblyName)).Returns(String.Empty); + + // Skip resources assembly + // newtonsoftAssemblyName does not contain a culture + + // Skip plugin dependencies + pluginDependencyContext.SetupGet(p => p.PluginDependencies).Returns(new[]{ + new PluginDependency + { + DependencyNameWithoutExtension = "not-the-droid-im-looking-for" + } + }); + + // Local file + fileSystemUtility.Setup(r => r.DoesFileExist($"{GetPathToAssemblies()}/{newtonsoftAssemblyName.Name}.dll")).Returns(true); + + var result = InvokeProtectedMethodOnLoadContextAndGetResult>( + loadContext, + "LoadFromDependencyContext", + new object[] { initialPluginLoadDirectory, newtonsoftAssemblyName }); + + Assert.IsNotNull(result); + Assert.AreEqual(newtonsoftAssemblyName.Name, result.Value.Assembly.GetName().Name); + } + + [TestMethod] + public async Task LoadFromDependencyContext_NothingFound_Returns_Proceed() + { + var testContext = await SetupLoadedPluginTextContext(); + var loadContext = testContext.Sut(); + var fileSystemUtility = testContext.GetMock(); + var runtimeDefaultAssemblyLoadContext = testContext.GetMock(); + var initialPluginLoadDirectory = testContext.InitialPluginLoadDirectory; + var pluginLoadContext = testContext.PluginLoadContext; + var newtonsoftAssemblyName = testContext.NewtonsoftAssemblyName; + var newtonsoftAssembly = testContext.NewtonsoftAssembly; + var newtonsoftAssemblyPath = testContext.NewtonsoftAssemblyPath; + var resolver = testContext.GetMock(); + var pluginDependencyContext = testContext.GetMock(); + var pluginDependencyResolver = testContext.GetMock(); + + // Skip the resolver + resolver.Setup(r => r.ResolveAssemblyToPath(newtonsoftAssemblyName)).Returns(String.Empty); + + // Skip resources assembly + // newtonsoftAssemblyName does not contain a culture + + // Skip plugin dependencies + pluginDependencyContext.SetupGet(p => p.PluginDependencies).Returns(new[]{ + new PluginDependency + { + DependencyNameWithoutExtension = "not-the-droid-im-looking-for" + } + }); + + // Local file + fileSystemUtility.Setup(r => r.DoesFileExist($"{GetPathToAssemblies()}/{newtonsoftAssemblyName.Name}.dll")).Returns(false); + + var result = InvokeProtectedMethodOnLoadContextAndGetResult>( + loadContext, + "LoadFromDependencyContext", + new object[] { initialPluginLoadDirectory, newtonsoftAssemblyName }); + Assert.IsNotNull(result); + Assert.IsTrue(result.CanProceed); + } + } +} \ No newline at end of file diff --git a/Vendor/Prise.Tests/AssemblyLoading/DefaultAssemblyLoadContextTests/DefaultAssemblyLoadContextTests_LoadFromRemote.cs b/Vendor/Prise.Tests/AssemblyLoading/DefaultAssemblyLoadContextTests/DefaultAssemblyLoadContextTests_LoadFromRemote.cs new file mode 100644 index 0000000..47db5d1 --- /dev/null +++ b/Vendor/Prise.Tests/AssemblyLoading/DefaultAssemblyLoadContextTests/DefaultAssemblyLoadContextTests_LoadFromRemote.cs @@ -0,0 +1,77 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Moq; +using Prise.AssemblyLoading; + +using Prise.Tests.Plugins; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Runtime.Loader; +using System.Threading.Tasks; + +namespace Prise.Tests.AssemblyLoading.DefaultAssemblyLoadContextTests +{ + [TestClass] + public class DefaultAssemblyLoadContextTests_LoadFromRemote : TestWithLoadedPluginBase + { + [TestMethod] + public async Task LoadFromRemote_Found_Returns_Assembly() + { + var testContext = await SetupLoadedPluginTextContext(); + var loadContext = testContext.Sut(); + var fileSystemUtility = testContext.GetMock(); + var runtimeDefaultAssemblyLoadContext = testContext.GetMock(); + var initialPluginLoadDirectory = testContext.InitialPluginLoadDirectory; + var pluginLoadContext = testContext.PluginLoadContext; + var newtonsoftAssemblyName = testContext.NewtonsoftAssemblyName; + var newtonsoftAssembly = testContext.NewtonsoftAssembly; + var newtonsoftAssemblyPath = testContext.NewtonsoftAssemblyPath; + var resolver = testContext.GetMock(); + var pluginDependencyContext = testContext.GetMock(); + + var newtonsoftAssemblyFileName = Path.GetFileName(newtonsoftAssemblyPath); + var newtonsoftAssemblyStream = File.OpenRead(newtonsoftAssemblyPath); + var newtonsoftAssemblyBytes = File.ReadAllBytes(newtonsoftAssemblyPath); + + fileSystemUtility.Setup(f => f.DoesFileExist($"{GetPathToAssemblies()}/{newtonsoftAssemblyFileName}")).Returns(true); + fileSystemUtility.Setup(f => f.ReadDependencyFileFromDisk(GetPathToAssemblies(), newtonsoftAssemblyFileName)).Returns(newtonsoftAssemblyStream); + fileSystemUtility.Setup(f => f.ToByteArray(newtonsoftAssemblyStream)).Returns(newtonsoftAssemblyBytes); + + var result = InvokeProtectedMethodOnLoadContextAndGetResult>( + loadContext, + "LoadFromRemote", + new object[] { initialPluginLoadDirectory, newtonsoftAssemblyName }); + + Assert.IsNotNull(result); + Assert.AreEqual(newtonsoftAssemblyName.Name, result.Value.Assembly.GetName().Name); + } + + [TestMethod] + public async Task LoadFromRemote_NothingFound_Returns_Proceed() + { + var testContext = await SetupLoadedPluginTextContext(); + var loadContext = testContext.Sut(); + var fileSystemUtility = testContext.GetMock(); + var runtimeDefaultAssemblyLoadContext = testContext.GetMock(); + var initialPluginLoadDirectory = testContext.InitialPluginLoadDirectory; + var pluginLoadContext = testContext.PluginLoadContext; + var newtonsoftAssemblyName = testContext.NewtonsoftAssemblyName; + var newtonsoftAssembly = testContext.NewtonsoftAssembly; + var newtonsoftAssemblyPath = testContext.NewtonsoftAssemblyPath; + var resolver = testContext.GetMock(); + var pluginDependencyContext = testContext.GetMock(); + + fileSystemUtility.Setup(f => f.DoesFileExist($"{GetPathToAssemblies()}/Newtonsoft.Json.dll")).Returns(false); + + var result = InvokeProtectedMethodOnLoadContextAndGetResult>( + loadContext, + "LoadFromRemote", + new object[] { initialPluginLoadDirectory, newtonsoftAssemblyName }); + + Assert.IsNotNull(result); + Assert.IsTrue(result.CanProceed); + } + } +} \ No newline at end of file diff --git a/Vendor/Prise.Tests/AssemblyLoading/DefaultAssemblyLoadContextTests/DefaultAssemblyLoadContextTests_LoadPluginAssembly.cs b/Vendor/Prise.Tests/AssemblyLoading/DefaultAssemblyLoadContextTests/DefaultAssemblyLoadContextTests_LoadPluginAssembly.cs new file mode 100644 index 0000000..a0fbb9c --- /dev/null +++ b/Vendor/Prise.Tests/AssemblyLoading/DefaultAssemblyLoadContextTests/DefaultAssemblyLoadContextTests_LoadPluginAssembly.cs @@ -0,0 +1,103 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Moq; +using Prise.AssemblyLoading; + +using Prise.Tests.Plugins; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Runtime.Loader; +using System.Threading.Tasks; + +namespace Prise.Tests.AssemblyLoading.DefaultAssemblyLoadContextTests +{ + [TestClass] + public class DefaultAssemblyLoadContextTests_LoadPluginAssembly : Base + { + [TestMethod] + public async Task Load_No_Context_Throws_ArgumentNullException() + { + var testContext = SetupAssemblyLoadContext(); + var loadContext = testContext.Sut(); + await Assert.ThrowsExceptionAsync(() => loadContext.LoadPluginAssembly(null)); + } + + [TestMethod] + public async Task Load_No_PathToAssembly_Throws_ArgumentNullException() + { + var testContext = SetupAssemblyLoadContext(); + var loadContext = testContext.Sut(); + var pluginLoadContext = new PluginLoadContext("Path To Plugin", this.GetType(), "netcoreapp3.1"); + pluginLoadContext.FullPathToPluginAssembly = null; + await Assert.ThrowsExceptionAsync(() => loadContext.LoadPluginAssembly(pluginLoadContext)); + } + + [TestMethod] + public async Task Load_UnRooted_PathToAssembly_Throws_ArgumentNullException() + { + var testContext = SetupAssemblyLoadContext(); + var loadContext = testContext.Sut(); + var pluginLoadContext = new PluginLoadContext("../testpath", this.GetType(), "netcoreapp3.1"); + await Assert.ThrowsExceptionAsync(() => loadContext.LoadPluginAssembly(pluginLoadContext)); + } + + [TestMethod] + public async Task LoadPluginAssembly_Works() + { + var pluginAssemblyPath = "/var/home/MyPluginAssembly.dll"; + var testContext = SetupAssemblyLoadContext(); + var loadContext = testContext.Sut(); + var fileSystemUtility = testContext.GetMock(); + var pluginDependencyContextProvider = testContext.GetMock(); + var pluginDependencyContext = testContext.GetMock(); + + var contract = TestableTypeBuilder.New() + .WithName("IMyTestType") + .WithNamespace("Test.Type") + .Build(); + + var assembly = this.GetType().Assembly; + var assemblyStream = File.OpenRead(assembly.Location); + + fileSystemUtility.Setup(f => f.EnsureFileExists(pluginAssemblyPath)).Returns(pluginAssemblyPath); + fileSystemUtility.Setup(f => f.ReadFileFromDisk(pluginAssemblyPath)).ReturnsAsync(assemblyStream); + var pluginLoadContext = new PluginLoadContext(pluginAssemblyPath, contract, "netcoreapp3.1"); + pluginDependencyContextProvider.Setup(p => p.FromPluginLoadContext(pluginLoadContext)).ReturnsAsync(pluginDependencyContext.Object); + + var priseAssembly = await loadContext.LoadPluginAssembly(pluginLoadContext); + + Assert.AreEqual(assembly.FullName, priseAssembly.Assembly.FullName); + } + + [TestMethod] + public async Task LoadPluginAssembly_Guard_Works() + { + var testContext = SetupAssemblyLoadContext(); + var loadContext = testContext.Sut(); + var fileSystemUtility = testContext.GetMock(); + var pluginAssemblyPath = "/var/home/MyPluginAssembly.dll"; + var pluginDependencyContextProvider = testContext.GetMock(); + var pluginDependencyContext = testContext.GetMock(); + + var contract = TestableTypeBuilder.New() + .WithName("IMyTestType") + .WithNamespace("Test.Type") + .Build(); + + var assembly = this.GetType().Assembly; + var assemblyStream = File.OpenRead(assembly.Location); + + fileSystemUtility.Setup(f => f.EnsureFileExists(pluginAssemblyPath)).Returns(pluginAssemblyPath); + fileSystemUtility.Setup(f => f.ReadFileFromDisk(pluginAssemblyPath)).ReturnsAsync(assemblyStream); + + var pluginLoadContext = new PluginLoadContext(pluginAssemblyPath, contract, "netcoreapp3.1"); + pluginDependencyContextProvider.Setup(p => p.FromPluginLoadContext(pluginLoadContext)).ReturnsAsync(pluginDependencyContext.Object); + + var priseAssembly = await loadContext.LoadPluginAssembly(pluginLoadContext); + + await Assert.ThrowsExceptionAsync(() => loadContext.LoadPluginAssembly(pluginLoadContext)); + } + } +} \ No newline at end of file diff --git a/Vendor/Prise.Tests/AssemblyLoading/DefaultAssemblyLoadContextTests/DefaultAssemblyLoadContextTests_LoadUnmanagedDll.cs b/Vendor/Prise.Tests/AssemblyLoading/DefaultAssemblyLoadContextTests/DefaultAssemblyLoadContextTests_LoadUnmanagedDll.cs new file mode 100644 index 0000000..c7615f1 --- /dev/null +++ b/Vendor/Prise.Tests/AssemblyLoading/DefaultAssemblyLoadContextTests/DefaultAssemblyLoadContextTests_LoadUnmanagedDll.cs @@ -0,0 +1,62 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Moq; +using Prise.AssemblyLoading; + +using Prise.Tests.Plugins; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Runtime.Loader; +using System.Threading.Tasks; + +namespace Prise.Tests.AssemblyLoading.DefaultAssemblyLoadContextTests +{ + [TestClass] + public class DefaultAssemblyLoadContextTests_LoadUnmanagedDll : TestWithLoadedPluginBase + { + [TestMethod] + public async Task Disposing_Prevents_LoadUnmanagedDll() + { + var testContext = SetupAssemblyLoadContext(); + var loadContext = testContext.Sut(); + + var assemblyName = this.GetType().Assembly.GetName().Name; + loadContext.Dispose(); + + var result = InvokeProtectedMethodOnLoadContextAndGetResult( + loadContext, + "LoadUnmanagedDll", + new object[] { assemblyName }); + + Assert.AreEqual(IntPtr.Zero, result); + } + + [TestMethod] + public async Task LoadUnmanagedDll_Works() + { + var testContext = await SetupLoadedPluginTextContext(); + var loadContext = testContext.Sut(); + var initialPluginLoadDirectory = testContext.InitialPluginLoadDirectory; + var assemblyLoadStrategy = testContext.GetMock(); + var pluginDependencyContext = testContext.GetMock(); + + var nativeDependency = "Nativelib.dll"; + var nativePtr = new IntPtr(1024 * 10000); + + assemblyLoadStrategy.Setup(a => a.LoadUnmanagedDll(initialPluginLoadDirectory, nativeDependency, pluginDependencyContext.Object, + It.IsAny>>(), + It.IsAny>>(), + It.IsAny>>())).Returns(NativeAssembly.Create(null, nativePtr)); + + var result = InvokeProtectedMethodOnLoadContextAndGetResult( + loadContext, + "LoadUnmanagedDll", + new object[] { nativeDependency }); + + Assert.IsNotNull(result); + Assert.AreEqual(nativePtr, result); + } + } +} \ No newline at end of file diff --git a/Vendor/Prise.Tests/AssemblyLoading/DefaultAssemblyLoadContextTests/DefaultAssemblyLoadContextTests_LoadUnmanagedFromDefault.cs b/Vendor/Prise.Tests/AssemblyLoading/DefaultAssemblyLoadContextTests/DefaultAssemblyLoadContextTests_LoadUnmanagedFromDefault.cs new file mode 100644 index 0000000..552821c --- /dev/null +++ b/Vendor/Prise.Tests/AssemblyLoading/DefaultAssemblyLoadContextTests/DefaultAssemblyLoadContextTests_LoadUnmanagedFromDefault.cs @@ -0,0 +1,36 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Moq; +using Prise.AssemblyLoading; + +using Prise.Tests.Plugins; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Runtime.Loader; +using System.Threading.Tasks; + +namespace Prise.Tests.AssemblyLoading.DefaultAssemblyLoadContextTests +{ + [TestClass] + public class DefaultAssemblyLoadContextTests_LoadUnmanagedFromDefault : TestWithLoadedPluginBase + { + [TestMethod] + public async Task LoadUnmanagedFromDefault_NotFound_Returns_ZeroPtrAndProceed() + { + var testContext = await SetupLoadedPluginTextContext((plc) => plc.NativeDependencyLoadPreference = NativeDependencyLoadPreference.PreferDependencyContext); + var loadContext = testContext.Sut(); + var initialPluginLoadDirectory = testContext.InitialPluginLoadDirectory; + + var nativeDependency = "not-found"; + var result = InvokeProtectedMethodOnLoadContextAndGetResult>( + loadContext, + "LoadUnmanagedFromDefault", + new object[] { initialPluginLoadDirectory, nativeDependency }); + + Assert.AreEqual(IntPtr.Zero, result.Value); + Assert.IsTrue(result.CanProceed); + } + } +} \ No newline at end of file diff --git a/Vendor/Prise.Tests/AssemblyLoading/DefaultAssemblyLoadContextTests/DefaultAssemblyLoadContextTests_LoadUnmanagedFromDependencyContext.cs b/Vendor/Prise.Tests/AssemblyLoading/DefaultAssemblyLoadContextTests/DefaultAssemblyLoadContextTests_LoadUnmanagedFromDependencyContext.cs new file mode 100644 index 0000000..27859cd --- /dev/null +++ b/Vendor/Prise.Tests/AssemblyLoading/DefaultAssemblyLoadContextTests/DefaultAssemblyLoadContextTests_LoadUnmanagedFromDependencyContext.cs @@ -0,0 +1,176 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Moq; +using Prise.AssemblyLoading; + +using Prise.Tests.Plugins; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Runtime.Loader; +using System.Threading.Tasks; + +namespace Prise.Tests.AssemblyLoading.DefaultAssemblyLoadContextTests +{ + [TestClass] + public class DefaultAssemblyLoadContextTests_LoadUnmanagedFromDependencyContext : TestWithLoadedPluginBase + { + [TestMethod] + public async Task LoadUnmanagedFromDependencyContext_PreferDependencyContext_Returns_LibraryPath() + { + var testContext = await SetupLoadedPluginTextContext((plc) => plc.NativeDependencyLoadPreference = NativeDependencyLoadPreference.PreferDependencyContext); + var loadContext = testContext.Sut(); + var initialPluginLoadDirectory = testContext.InitialPluginLoadDirectory; + var resolver = testContext.GetMock(); + + var nativeDependency = "Nativelib.dll"; + var libraryPath = "/var/path/to/Nativelib.dll"; + resolver.Setup(r => r.ResolveUnmanagedDllToPath(nativeDependency)).Returns(libraryPath); + + var result = InvokeProtectedMethodOnLoadContextAndGetResult>( + loadContext, + "LoadUnmanagedFromDependencyContext", + new object[] { initialPluginLoadDirectory, nativeDependency }); + + Assert.IsNotNull(result.Value); + Assert.AreEqual(libraryPath, result.Value); + Assert.IsFalse(result.CanProceed); + } + + [TestMethod] + public async Task LoadUnmanagedFromDependencyContext_PreferInstalledRuntime_Returns_LibraryPath() + { + var testContext = await SetupLoadedPluginTextContext((plc) => plc.NativeDependencyLoadPreference = NativeDependencyLoadPreference.PreferInstalledRuntime); + var loadContext = testContext.Sut(); + var initialPluginLoadDirectory = testContext.InitialPluginLoadDirectory; + var resolver = testContext.GetMock(); + var pluginDependencyResolver = testContext.GetMock(); + + var nativeDependency = "Nativelib.dll"; + var libraryPath = "/var/path/to/Nativelib.dll"; + var runtimeCandidate = "/var/path/to/runtime/Nativelib.dll"; + resolver.Setup(r => r.ResolveUnmanagedDllToPath(nativeDependency)).Returns(libraryPath); + pluginDependencyResolver.Setup(r => r.ResolvePlatformDependencyPathToRuntime(It.IsAny(), libraryPath)).Returns(runtimeCandidate); + + var result = InvokeProtectedMethodOnLoadContextAndGetResult>( + loadContext, + "LoadUnmanagedFromDependencyContext", + new object[] { initialPluginLoadDirectory, nativeDependency }); + + Assert.IsNotNull(result.Value); + Assert.AreEqual(runtimeCandidate, result.Value); + Assert.IsFalse(result.CanProceed); + } + + [TestMethod] + public async Task LoadUnmanagedFromDependencyContext_PreferDependencyContext_Returns_PlatformDependency() + { + var testContext = await SetupLoadedPluginTextContext((plc) => plc.NativeDependencyLoadPreference = NativeDependencyLoadPreference.PreferDependencyContext); + var loadContext = testContext.Sut(); + var initialPluginLoadDirectory = testContext.InitialPluginLoadDirectory; + var resolver = testContext.GetMock(); + var pluginDependencyContext = testContext.GetMock(); + var pluginDependencyResolver = testContext.GetMock(); + + var nativeDependency = "Nativelib.dll"; + var pathToDependency = "/var/path/to/dependency/Nativelib.dll"; + resolver.Setup(r => r.ResolveUnmanagedDllToPath(nativeDependency)).Returns((string)null); + var platformDependency = new PlatformDependency + { + DependencyNameWithoutExtension = "Nativelib" + }; + + var additionalProbingPaths = Enumerable.Empty(); + pluginDependencyContext.SetupGet(c => c.AdditionalProbingPaths).Returns(additionalProbingPaths); + pluginDependencyContext.SetupGet(c => c.PlatformDependencies).Returns(new[]{ + platformDependency, + new PlatformDependency + { + DependencyNameWithoutExtension = "OtherNativelib" + } + }); + pluginDependencyResolver + .Setup(r => r.ResolvePlatformDependencyToPath(initialPluginLoadDirectory, platformDependency, additionalProbingPaths)) + .Returns(pathToDependency); + + var result = InvokeProtectedMethodOnLoadContextAndGetResult>( + loadContext, + "LoadUnmanagedFromDependencyContext", + new object[] { initialPluginLoadDirectory, nativeDependency }); + + Assert.IsNotNull(result.Value); + Assert.AreEqual(pathToDependency, result.Value); + Assert.IsFalse(result.CanProceed); + } + + [TestMethod] + public async Task LoadUnmanagedFromDependencyContext_PreferInstalledRuntime_Returns_RuntimeCandidate() + { + var testContext = await SetupLoadedPluginTextContext((plc) => plc.NativeDependencyLoadPreference = NativeDependencyLoadPreference.PreferInstalledRuntime); + var loadContext = testContext.Sut(); + var initialPluginLoadDirectory = testContext.InitialPluginLoadDirectory; + var resolver = testContext.GetMock(); + var pluginDependencyContext = testContext.GetMock(); + var pluginDependencyResolver = testContext.GetMock(); + + var nativeDependency = "Nativelib.dll"; + var pathToDependency = "/var/path/to/dependency/Nativelib.dll"; + var runtimeCandidate = "/var/path/to/runtime/Nativelib.dll"; + resolver.Setup(r => r.ResolveUnmanagedDllToPath(nativeDependency)).Returns((string)null); + var platformDependency = new PlatformDependency + { + DependencyNameWithoutExtension = "Nativelib" + }; + var additionalProbingPaths = Enumerable.Empty(); + pluginDependencyContext.SetupGet(c => c.AdditionalProbingPaths).Returns(additionalProbingPaths); + pluginDependencyContext.SetupGet(c => c.PlatformDependencies).Returns(new[]{ + platformDependency, + new PlatformDependency + { + DependencyNameWithoutExtension = "OtherNativelib" + } + }); + pluginDependencyResolver + .Setup(r => r.ResolvePlatformDependencyToPath(initialPluginLoadDirectory, platformDependency, additionalProbingPaths)) + .Returns(pathToDependency); + pluginDependencyResolver.Setup(r => r.ResolvePlatformDependencyPathToRuntime(It.IsAny(), pathToDependency)).Returns(runtimeCandidate); + + var result = InvokeProtectedMethodOnLoadContextAndGetResult>( + loadContext, + "LoadUnmanagedFromDependencyContext", + new object[] { initialPluginLoadDirectory, nativeDependency }); + + Assert.IsNotNull(result.Value); + Assert.AreEqual(runtimeCandidate, result.Value); + Assert.IsFalse(result.CanProceed); + } + + [TestMethod] + public async Task LoadUnmanagedFromDependencyContext_NothingFound_Returns_Empty_And_Proceed() + { + var testContext = await SetupLoadedPluginTextContext((plc) => plc.NativeDependencyLoadPreference = NativeDependencyLoadPreference.PreferInstalledRuntime); + var loadContext = testContext.Sut(); + var initialPluginLoadDirectory = testContext.InitialPluginLoadDirectory; + var resolver = testContext.GetMock(); + var pluginDependencyContext = testContext.GetMock(); + + var nativeDependency = "Nativelib.dll"; + resolver.Setup(r => r.ResolveUnmanagedDllToPath(nativeDependency)).Returns((string)null); + pluginDependencyContext.SetupGet(c => c.PlatformDependencies).Returns(new[]{ + new PlatformDependency + { + DependencyNameWithoutExtension = "OtherNativelib" + } + }); + + var result = InvokeProtectedMethodOnLoadContextAndGetResult>( + loadContext, + "LoadUnmanagedFromDependencyContext", + new object[] { initialPluginLoadDirectory, nativeDependency }); + + Assert.AreEqual(String.Empty, result.Value); + Assert.IsTrue(result.CanProceed); + } + } +} \ No newline at end of file diff --git a/Vendor/Prise.Tests/AssemblyLoading/DefaultAssemblyLoadContextTests/DefaultAssemblyLoadContextTests_LoadUnmanagedFromRemote.cs b/Vendor/Prise.Tests/AssemblyLoading/DefaultAssemblyLoadContextTests/DefaultAssemblyLoadContextTests_LoadUnmanagedFromRemote.cs new file mode 100644 index 0000000..75aa7c9 --- /dev/null +++ b/Vendor/Prise.Tests/AssemblyLoading/DefaultAssemblyLoadContextTests/DefaultAssemblyLoadContextTests_LoadUnmanagedFromRemote.cs @@ -0,0 +1,62 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Moq; +using Prise.AssemblyLoading; + +using Prise.Tests.Plugins; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Runtime.Loader; +using System.Threading.Tasks; + +namespace Prise.Tests.AssemblyLoading.DefaultAssemblyLoadContextTests +{ + [TestClass] + public class DefaultAssemblyLoadContextTests_LoadUnmanagedFromRemote : TestWithLoadedPluginBase + { + [TestMethod] + public async Task LoadUnmanagedFromRemote_Returns_PathToDependency() + { + var testContext = await SetupLoadedPluginTextContext((plc) => plc.NativeDependencyLoadPreference = NativeDependencyLoadPreference.PreferDependencyContext); + var loadContext = testContext.Sut(); + var fileSystemUtility = testContext.GetMock(); + var initialPluginLoadDirectory = testContext.InitialPluginLoadDirectory; + + var nativeDependency = "Nativelib"; + var pathToDependency = $"{initialPluginLoadDirectory}/Nativelib.dll"; + fileSystemUtility.Setup(f => f.DoesFileExist(pathToDependency)).Returns(true); + + var result = InvokeProtectedMethodOnLoadContextAndGetResult>( + loadContext, + "LoadUnmanagedFromRemote", + new object[] { initialPluginLoadDirectory, nativeDependency }); + + Assert.IsNotNull(result.Value); + Assert.AreEqual(pathToDependency, result.Value); + Assert.IsFalse(result.CanProceed); + } + + [TestMethod] + public async Task LoadUnmanagedFromRemote_NothingFound_Returns_EmtpyAndProceed() + { + var testContext = await SetupLoadedPluginTextContext((plc) => plc.NativeDependencyLoadPreference = NativeDependencyLoadPreference.PreferDependencyContext); + var loadContext = testContext.Sut(); + var fileSystemUtility = testContext.GetMock(); + var initialPluginLoadDirectory = testContext.InitialPluginLoadDirectory; + + var nativeDependency = "Nativelib"; + var pathToDependency = $"{initialPluginLoadDirectory}/Nativelib.dll"; + fileSystemUtility.Setup(f => f.DoesFileExist(pathToDependency)).Returns(false); + + var result = InvokeProtectedMethodOnLoadContextAndGetResult>( + loadContext, + "LoadUnmanagedFromRemote", + new object[] { initialPluginLoadDirectory, nativeDependency }); + + Assert.AreEqual(String.Empty, result.Value); + Assert.IsTrue(result.CanProceed); + } + } +} \ No newline at end of file diff --git a/Vendor/Prise.Tests/AssemblyLoading/DefaultAssemblyLoadStrategyTests.cs b/Vendor/Prise.Tests/AssemblyLoading/DefaultAssemblyLoadStrategyTests.cs new file mode 100644 index 0000000..d7c4ae2 --- /dev/null +++ b/Vendor/Prise.Tests/AssemblyLoading/DefaultAssemblyLoadStrategyTests.cs @@ -0,0 +1,222 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Moq; +using Prise.AssemblyLoading; + +using Prise.Tests.Plugins; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Runtime.Loader; +using System.Threading.Tasks; + +namespace Prise.Tests.AssemblyLoading +{ + [TestClass] + public class DefaultAssemblyLoadStrategyTests : TestBase + { + [TestMethod] + public async Task Ctor_Works() + { + Assert.IsNotNull(new DefaultAssemblyLoadStrategy()); + } + + [TestMethod] + public async Task LoadAssembly_Returns_Null_For_Empty_AssemblyName() + { + var sut = new DefaultAssemblyLoadStrategy(); + var emptyAssemblyname = new AssemblyName(); + var initialPluginLoadDirectory = GetPathToAssemblies(); + + Assert.IsNull(sut.LoadAssembly(initialPluginLoadDirectory, emptyAssemblyname, null, null, null, null)?.Assembly); + } + + [TestMethod] + public async Task LoadAssembly_Returns_Null_When_AssemblyName_NotFound() + { + var sut = new DefaultAssemblyLoadStrategy(); + var assemblyname = new AssemblyName("Newtonsoft.Json.dll"); + var pluginDependencyContext = this.mockRepository.Create(); + var loadFromDependencyContext = CreateLookupFunction((c, a) => ValueOrProceed.Proceed()); + var loadFromRemote = CreateLookupFunction((c, a) => ValueOrProceed.Proceed()); + var loadFromAppDomain = CreateLookupFunction((c, a) => ValueOrProceed.Proceed()); + var initialPluginLoadDirectory = GetPathToAssemblies(); + + pluginDependencyContext + .Setup(p => p.HostDependencies).Returns(Enumerable.Empty()); + + pluginDependencyContext + .Setup(p => p.RemoteDependencies).Returns(Enumerable.Empty()); + + Assert.IsNull(sut.LoadAssembly(initialPluginLoadDirectory, assemblyname, pluginDependencyContext.Object, loadFromDependencyContext, loadFromRemote, loadFromAppDomain)?.Assembly); + } + + [TestMethod] + public async Task LoadAssembly_Returns_Null_From_AppDomain_When_IsHostAssembly_And_Not_RemoteAssembly() + { + var sut = new DefaultAssemblyLoadStrategy(); + var pluginDependencyContext = this.mockRepository.Create(); + var initialPluginLoadDirectory = GetPathToAssemblies(); + var someAssembly = Assembly.LoadFile(Path.Combine(initialPluginLoadDirectory, "Newtonsoft.Json.dll")); + var someAssemblyName = someAssembly.GetName(); + var loadFromDependencyContext = CreateLookupFunction((c, a) => ValueOrProceed.Proceed()); + var loadFromRemote = CreateLookupFunction((c, a) => ValueOrProceed.Proceed()); + var loadFromAppDomain = CreateLookupFunction((c, a) => ValueOrProceed.FromValue(new RuntimeAssemblyShim(someAssembly, RuntimeLoadFlag.FromRequestedVersion), false)); + + // Mock the fact that it was setup as a host assembly that should be loaded from the host. + pluginDependencyContext + .Setup(p => p.HostDependencies).Returns(new List { new HostDependency { DependencyName = someAssemblyName } }); + + pluginDependencyContext + .Setup(p => p.RemoteDependencies).Returns(Enumerable.Empty()); + + Assert.IsNull(sut.LoadAssembly(initialPluginLoadDirectory, someAssemblyName, pluginDependencyContext.Object, loadFromDependencyContext, loadFromRemote, loadFromAppDomain)?.Assembly); + } + + [TestMethod] + public async Task LoadAssembly_Returns_NotNull_From_AppDomain_When_IsHostAssembly_And_Not_RemoteAssembly_FromRuntimeVersion() + { + var sut = new DefaultAssemblyLoadStrategy(); + var pluginDependencyContext = this.mockRepository.Create(); + var initialPluginLoadDirectory = GetPathToAssemblies(); + var someAssembly = Assembly.LoadFile(Path.Combine(initialPluginLoadDirectory, "Newtonsoft.Json.dll")); + var someAssemblyName = someAssembly.GetName(); + var loadFromDependencyContext = CreateLookupFunction((c, a) => ValueOrProceed.Proceed()); + var loadFromRemote = CreateLookupFunction((c, a) => ValueOrProceed.Proceed()); + var loadFromAppDomain = CreateLookupFunction((c, a) => ValueOrProceed.FromValue(new RuntimeAssemblyShim(someAssembly, RuntimeLoadFlag.FromRuntimeVersion), false)); + + // Mock the fact that it was setup as a host assembly that should be loaded from the host. + pluginDependencyContext + .Setup(p => p.HostDependencies).Returns(new List { new HostDependency { DependencyName = someAssemblyName } }); + + pluginDependencyContext + .Setup(p => p.RemoteDependencies).Returns(Enumerable.Empty()); + + Assert.AreEqual(someAssembly, sut.LoadAssembly(initialPluginLoadDirectory, someAssemblyName, pluginDependencyContext.Object, loadFromDependencyContext, loadFromRemote, loadFromAppDomain)?.Assembly); + } + + [TestMethod] + public async Task LoadAssembly_Returns_Null_From_AppDomain_When_NOT_IsHostAssembly_And_RemoteAssembly() + { + var sut = new DefaultAssemblyLoadStrategy(); + var pluginDependencyContext = this.mockRepository.Create(); + var initialPluginLoadDirectory = GetPathToAssemblies(); + var someAssembly = Assembly.LoadFile(Path.Combine(initialPluginLoadDirectory, "Newtonsoft.Json.dll")); + var someAssemblyName = someAssembly.GetName(); + var loadFromDependencyContext = CreateLookupFunction((c, a) => ValueOrProceed.Proceed()); + var loadFromRemote = CreateLookupFunction((c, a) => ValueOrProceed.Proceed()); + var loadFromAppDomain = CreateLookupFunction((c, a) => ValueOrProceed.Proceed()); + + // Mock the fact that it was setup as a host assembly that should be loaded from the host. + pluginDependencyContext + .Setup(p => p.HostDependencies).Returns(new List { new HostDependency { DependencyName = someAssemblyName } }); + + // Mock the fact that it was ALSO setup as a remote assembly that should be loaded from the plugin. + pluginDependencyContext + .Setup(p => p.RemoteDependencies).Returns(new List { new RemoteDependency { DependencyName = someAssemblyName } }); + + Assert.IsNull(sut.LoadAssembly(initialPluginLoadDirectory, someAssemblyName, pluginDependencyContext.Object, loadFromDependencyContext, loadFromRemote, loadFromAppDomain)?.Assembly); + } + + [TestMethod] + public async Task LoadAssembly_Returns_Assembly_From_DependencyContext() + { + var sut = new DefaultAssemblyLoadStrategy(); + var pluginDependencyContext = this.mockRepository.Create(); + var initialPluginLoadDirectory = GetPathToAssemblies(); + var someAssembly = Assembly.LoadFile(Path.Combine(initialPluginLoadDirectory, "Newtonsoft.Json.dll")); + var someAssemblyName = someAssembly.GetName(); + var loadFromDependencyContext = CreateLookupFunction((c, a) => ValueOrProceed.FromValue(AssemblyFromStrategy.Releasable(someAssembly), false)); + var loadFromRemote = CreateLookupFunction((c, a) => ValueOrProceed.Proceed()); + var loadFromAppDomain = CreateLookupFunction((c, a) => ValueOrProceed.Proceed()); + + pluginDependencyContext + .Setup(p => p.HostDependencies).Returns(Enumerable.Empty()); + + pluginDependencyContext + .Setup(p => p.RemoteDependencies).Returns(Enumerable.Empty()); + + Assert.AreEqual(someAssembly, sut.LoadAssembly(initialPluginLoadDirectory, someAssemblyName, pluginDependencyContext.Object, loadFromDependencyContext, loadFromRemote, loadFromAppDomain)?.Assembly); + } + + [TestMethod] + public async Task LoadAssembly_Returns_Assembly_From_Remote() + { + var sut = new DefaultAssemblyLoadStrategy(); + var pluginDependencyContext = this.mockRepository.Create(); + var initialPluginLoadDirectory = GetPathToAssemblies(); + var someAssembly = Assembly.LoadFile(Path.Combine(initialPluginLoadDirectory, "Newtonsoft.Json.dll")); + var someAssemblyName = someAssembly.GetName(); + var loadFromDependencyContext = CreateLookupFunction((c, a) => ValueOrProceed.Proceed()); + var loadFromRemote = CreateLookupFunction((c, a) => ValueOrProceed.FromValue(AssemblyFromStrategy.Releasable(someAssembly), false)); + var loadFromAppDomain = CreateLookupFunction((c, a) => ValueOrProceed.Proceed()); + + pluginDependencyContext + .Setup(p => p.HostDependencies).Returns(Enumerable.Empty()); + + pluginDependencyContext + .Setup(p => p.RemoteDependencies).Returns(Enumerable.Empty()); + + Assert.AreEqual(someAssembly, sut.LoadAssembly(initialPluginLoadDirectory, someAssemblyName, pluginDependencyContext.Object, loadFromDependencyContext, loadFromRemote, loadFromAppDomain)?.Assembly); + } + + [TestMethod] + public async Task LoadUnmanagedDll_Returns_AssemblyPath_FromDependencyContext() + { + var sut = new DefaultAssemblyLoadStrategy(); + var pluginDependencyContext = this.mockRepository.Create(); + var initialPluginLoadDirectory = GetPathToAssemblies(); + var someAssembly = Assembly.LoadFile(Path.Combine(initialPluginLoadDirectory, "Newtonsoft.Json.dll")); + var someAssemblyName = someAssembly.GetName(); + var loadFromDependencyContext = CreateLookupFunction((c, a) => ValueOrProceed.FromValue(someAssemblyName.Name, false)); + var loadFromRemote = CreateLookupFunction((c, a) => ValueOrProceed.Proceed()); + var loadFromAppDomain = CreateLookupFunction((c, a) => ValueOrProceed.FromValue(IntPtr.Zero, false)); + + var result = sut.LoadUnmanagedDll(initialPluginLoadDirectory, someAssemblyName.Name, pluginDependencyContext.Object, loadFromDependencyContext, loadFromRemote, loadFromAppDomain); + + Assert.AreEqual(someAssemblyName.Name, result.Path); + Assert.AreEqual(IntPtr.Zero, result.Pointer); + } + + [TestMethod] + public async Task LoadUnmanagedDll_Returns_AssemblyPointer_FromAppDomain() + { + var sut = new DefaultAssemblyLoadStrategy(); + var pluginDependencyContext = this.mockRepository.Create(); + var initialPluginLoadDirectory = GetPathToAssemblies(); + var someAssembly = Assembly.LoadFile(Path.Combine(initialPluginLoadDirectory, "Newtonsoft.Json.dll")); + var someAssemblyName = someAssembly.GetName(); + var loadFromDependencyContext = CreateLookupFunction((c, a) => ValueOrProceed.Proceed()); + var loadFromRemote = CreateLookupFunction((c, a) => ValueOrProceed.Proceed()); + var loadFromAppDomain = CreateLookupFunction((c, a) => ValueOrProceed.FromValue(new IntPtr(100), false)); + + var result = sut.LoadUnmanagedDll(initialPluginLoadDirectory, someAssemblyName.Name, pluginDependencyContext.Object, loadFromDependencyContext, loadFromRemote, loadFromAppDomain); + + Assert.IsNull(result.Path); + Assert.AreEqual(new IntPtr(100), result.Pointer); + } + + [TestMethod] + public async Task LoadUnmanagedDll_Returns_AssemblyPath_FromRemote() + { + var sut = new DefaultAssemblyLoadStrategy(); + var pluginDependencyContext = this.mockRepository.Create(); + var initialPluginLoadDirectory = GetPathToAssemblies(); + var someAssembly = Assembly.LoadFile(Path.Combine(initialPluginLoadDirectory, "Newtonsoft.Json.dll")); + var someAssemblyName = someAssembly.GetName(); + var loadFromDependencyContext = CreateLookupFunction((c, a) => ValueOrProceed.Proceed()); + var loadFromRemote = CreateLookupFunction((c, a) => ValueOrProceed.FromValue(someAssemblyName.Name, false)); + var loadFromAppDomain = CreateLookupFunction((c, a) => ValueOrProceed.Proceed()); + + var result = sut.LoadUnmanagedDll(initialPluginLoadDirectory, someAssemblyName.Name, pluginDependencyContext.Object, loadFromDependencyContext, loadFromRemote, loadFromAppDomain); + + Assert.AreEqual(someAssemblyName.Name, result.Path); + Assert.AreEqual(IntPtr.Zero, result.Pointer); + } + + protected Func> CreateLookupFunction(Func> func) => func; + protected Func> CreateLookupFunction(Func> func) => func; + protected Func> CreateLookupFunction(Func> func) => func; + } +} \ No newline at end of file diff --git a/Vendor/Prise.Tests/AssemblyLoading/DefaultAssemblyLoaderTests.cs b/Vendor/Prise.Tests/AssemblyLoading/DefaultAssemblyLoaderTests.cs new file mode 100644 index 0000000..b537fda --- /dev/null +++ b/Vendor/Prise.Tests/AssemblyLoading/DefaultAssemblyLoaderTests.cs @@ -0,0 +1,110 @@ + +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Moq; +using Prise.AssemblyLoading; +using Prise.AssemblyScanning; + +using Prise.Tests.Plugins; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Threading.Tasks; + +namespace Prise.Tests.AssemblyLoading +{ + [TestClass] + public class DefaultAssemblyLoaderTests : TestBase + { + [TestMethod] + public void Ctor_No_AssemblyLoadContextFactory_Throws_ArgumentNullException() + { + var exception = Assert.ThrowsException(() => new DefaultAssemblyLoader(null)); + exception.Message.Contains("assemblyLoadContextFactory"); + } + + [TestMethod] + public void Ctor_Works() + { + Assert.IsNotNull(new DefaultAssemblyLoader(() => null)); + } + + [TestMethod] + public async Task Load_No_Context_Throws_ArgumentNullException() + { + var loader = new DefaultAssemblyLoader(() => null); + await Assert.ThrowsExceptionAsync(() => loader.Load(null)); + } + + [TestMethod] + public async Task Load_No_PathToAssembly_Throws_ArgumentNullException() + { + var loader = new DefaultAssemblyLoader(() => null); + var loadContext = new PluginLoadContext("Path To Plugin", this.GetType(), "netcoreapp3.1"); + loadContext.FullPathToPluginAssembly = null; + await Assert.ThrowsExceptionAsync(() => loader.Load(loadContext)); + } + + [TestMethod] + public async Task Load_UnRooted_PathToAssembly_Throws_ArgumentNullException() + { + var loader = new DefaultAssemblyLoader(() => null); + var loadContext = new PluginLoadContext("../testpath", this.GetType(), "netcoreapp3.1"); + await Assert.ThrowsExceptionAsync(() => loader.Load(loadContext)); + } + + [TestMethod] + public async Task Load_Works() + { + var mockLoadContext = this.mockRepository.Create(); + var assemblyShim = this.mockRepository.Create(); + var loader = new DefaultAssemblyLoader(() => mockLoadContext.Object); + var loadContext = new PluginLoadContext("/home/maarten/assembly.dll", this.GetType(), "netcoreapp3.1"); + mockLoadContext.Setup(c => c.LoadPluginAssembly(loadContext)).ReturnsAsync(assemblyShim.Object); + + var assembly = await loader.Load(loadContext); + + Assert.AreEqual(assemblyShim.Object, assembly); + } + + [TestMethod] + public async Task Unload_No_Context_Throws_ArgumentNullException() + { + var loader = new DefaultAssemblyLoader(() => null); + await Assert.ThrowsExceptionAsync(() => loader.Unload(null)); + } + + [TestMethod] + public async Task Unload_No_PathToAssembly_Throws_ArgumentNullException() + { + var loader = new DefaultAssemblyLoader(() => null); + var loadContext = new PluginLoadContext("Path To Plugin", this.GetType(), "netcoreapp3.1"); + loadContext.FullPathToPluginAssembly = null; + await Assert.ThrowsExceptionAsync(() => loader.Unload(loadContext)); + } + + [TestMethod] + public async Task Unload_UnRooted_PathToAssembly_Throws_ArgumentNullException() + { + var loader = new DefaultAssemblyLoader(() => null); + var loadContext = new PluginLoadContext("../testpath", this.GetType(), "netcoreapp3.1"); + await Assert.ThrowsExceptionAsync(() => loader.Unload(loadContext)); + } + + [TestMethod] + public async Task Unload_Works() + { + var mockLoadContext = this.mockRepository.Create(); + var assemblyShim = this.mockRepository.Create(); + var loader = new DefaultAssemblyLoader(() => mockLoadContext.Object); + var loadContext = new PluginLoadContext("/home/maarten/assembly.dll", this.GetType(), "netcoreapp3.1"); + mockLoadContext.Setup(c => c.LoadPluginAssembly(loadContext)).ReturnsAsync(assemblyShim.Object); + + var assembly = await loader.Load(loadContext); + await loader.Unload(loadContext); + + Assert.AreEqual(assemblyShim.Object, assembly); + } + } +} \ No newline at end of file diff --git a/Vendor/Prise.Tests/AssemblyScanning/DefaultAssemblyScannerTests.cs b/Vendor/Prise.Tests/AssemblyScanning/DefaultAssemblyScannerTests.cs new file mode 100644 index 0000000..9d5a980 --- /dev/null +++ b/Vendor/Prise.Tests/AssemblyScanning/DefaultAssemblyScannerTests.cs @@ -0,0 +1,121 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Moq; +using Prise.AssemblyScanning; + +using Prise.Tests.Plugins; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Threading.Tasks; + +namespace Prise.Tests.AssemblyScanning +{ + [TestClass] + public class DefaultAssemblyScannerTests : TestBase + { + [TestMethod] + public void Ctor_No_MetadataLoadContextFactory_Throws_ArgumentNullException() + { + var exception = Assert.ThrowsException(() => new DefaultAssemblyScanner(null, null)); + exception.Message.Contains("metadataLoadContextFactory"); + } + + [TestMethod] + public void Ctor_No_DirectoryTraverserFactory_Throws_ArgumentNullException() + { + var exception = Assert.ThrowsException(() => new DefaultAssemblyScanner((s) => null, null)); + exception.Message.Contains("directoryTraverser"); + } + + [TestMethod] + public async Task Scan_No_Options_Throws_ArgumentNullException() + { + var scanner = new DefaultAssemblyScanner((s) => null, () => null); + await Assert.ThrowsExceptionAsync(() => scanner.Scan(null)); + } + + [TestMethod] + public async Task Scan_No_StartingPath_Throws_ArgumentException() + { + var scanner = new DefaultAssemblyScanner((s) => null, () => null); + await Assert.ThrowsExceptionAsync(() => scanner.Scan(new AssemblyScannerOptions + { + PluginType = typeof(ITestPlugin) + })); + } + + [TestMethod] + public async Task Scan_No_PluginType_Throws_ArgumentException() + { + var scanner = new DefaultAssemblyScanner((s) => null, () => null); + await Assert.ThrowsExceptionAsync(() => scanner.Scan(new AssemblyScannerOptions + { + StartingPath = "/home/maarten" + })); + } + + [TestMethod] + public async Task Scan_Unrooted_Path_Throws_AssemblyScanningException() + { + var scanner = new DefaultAssemblyScanner((s) => null, () => null); + await Assert.ThrowsExceptionAsync(() => scanner.Scan(new AssemblyScannerOptions + { + StartingPath = "../home/maarten", + PluginType = typeof(ITestPlugin) + })); + } + + [TestMethod] + public async Task Scan_Succeeds() + { + var startingPath = "/home/maarten"; + var metadataLoadContext = this.mockRepository.Create(); + var assemblyShim = this.mockRepository.Create(); + var directoryTraverser = this.mockRepository.Create(); + + directoryTraverser.Setup(d => d.TraverseDirectories(startingPath)).Returns(new[] { "pathy/mcpathface" }); + directoryTraverser.Setup(d => d.TraverseFiles(It.IsAny(), It.IsAny>())).Returns(new[] { "filey.mcfile.face" }); + + var contract = TestableTypeBuilder.New() + .WithName("IMyTestType") + .WithNamespace("Test.Type") + .Build(); + + var pluginAttributeTypedValue = new CustomAttributeTypedArgument(contract); + var pluginAttribute = new TestableAttribute + { + _AttributeType = typeof(Prise.Plugin.PluginAttribute), + _NamedArguments = new[]{new CustomAttributeNamedArgument(new TestableMemberInfo{ + _Name = "PluginType" + },pluginAttributeTypedValue)} + }; + + var testableType = TestableTypeBuilder.New() + .WithCustomAttributes(pluginAttribute) + .WithName("MyTestType") + .WithNamespace("Test.Type") + .Build(); + + assemblyShim.Setup(a => a.Types).Returns(new[] { testableType }); + + metadataLoadContext.Setup(c => c.LoadFromAssemblyName(It.IsAny())).Returns(assemblyShim.Object); + + var scanner = new DefaultAssemblyScanner( + (s) => metadataLoadContext.Object, + () => directoryTraverser.Object + ); + var types = await scanner.Scan(new AssemblyScannerOptions + { + StartingPath = startingPath, + PluginType = contract + }); + + var result = types.FirstOrDefault(); + Assert.IsNotNull(result); + Assert.AreEqual("MyTestType", result.PluginType.Name); + Assert.AreEqual("Test.Type", result.PluginType.Namespace); + } + } +} \ No newline at end of file diff --git a/Vendor/Prise.Tests/AssemblyScanning/DefaultNugetPackageAssemblyScannerTests.cs b/Vendor/Prise.Tests/AssemblyScanning/DefaultNugetPackageAssemblyScannerTests.cs new file mode 100644 index 0000000..7b03747 --- /dev/null +++ b/Vendor/Prise.Tests/AssemblyScanning/DefaultNugetPackageAssemblyScannerTests.cs @@ -0,0 +1,321 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Moq; +using Prise.AssemblyScanning; + +using Prise.Tests.Plugins; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Threading.Tasks; + +namespace Prise.Tests.AssemblyScanning +{ + [TestClass] + public class DefaultNugetPackageAssemblyScannerTests : TestBase + { + [TestMethod] + public void Ctor_No_NugetUtilitiesFactory_Throws_ArgumentNullException() + { + var exception = Assert.ThrowsException(() => new DefaultNugetPackageAssemblyScanner((s) => null, () => null, null)); + exception.Message.Contains("nugetPackageUtilities"); + } + + [TestMethod] + public async Task Scan_No_Options_Throws_ArgumentNullException() + { + var scanner = new DefaultNugetPackageAssemblyScanner((s) => null, () => null, () => null); + await Assert.ThrowsExceptionAsync(() => scanner.Scan(null)); + } + + [TestMethod] + public async Task Scan_No_StartingPath_Throws_ArgumentException() + { + var scanner = new DefaultNugetPackageAssemblyScanner((s) => null, () => null, () => null); + await Assert.ThrowsExceptionAsync(() => scanner.Scan(new AssemblyScannerOptions + { + PluginType = typeof(ITestPlugin) + })); + } + + [TestMethod] + public async Task Scan_No_PluginType_Throws_ArgumentException() + { + var scanner = new DefaultNugetPackageAssemblyScanner((s) => null, () => null, () => null); + await Assert.ThrowsExceptionAsync(() => scanner.Scan(new AssemblyScannerOptions + { + StartingPath = "/home/maarten" + })); + } + + [TestMethod] + public async Task Scan_Unrooted_Path_Throws_AssemblyScanningException() + { + var scanner = new DefaultNugetPackageAssemblyScanner((s) => null, () => null, () => null); + await Assert.ThrowsExceptionAsync(() => scanner.Scan(new AssemblyScannerOptions + { + StartingPath = "../home/maarten", + PluginType = typeof(ITestPlugin) + })); + } + + + [TestMethod] + public async Task Scan_No_Nugets_Throws_AssemblyScanningException() + { + var startingPath = "/home/maarten"; + var nugetUtilities = this.mockRepository.Create(); + nugetUtilities.Setup(n => n.FindAllNugetPackagesFiles(startingPath)).Returns(Enumerable.Empty()); + var scanner = new DefaultNugetPackageAssemblyScanner((s) => null, () => null, () => nugetUtilities.Object); + + await Assert.ThrowsExceptionAsync(() => scanner.Scan(new AssemblyScannerOptions + { + StartingPath = startingPath, + PluginType = typeof(ITestPlugin) + })); + } + + [TestMethod] + public async Task Compressed_NugetPackage_Must_Be_UnCompressed() + { + var package = "Prise.Plugin.Package.1.0.0.nupkg"; + var startingPath = "/home/maarten"; + var nugetUtilities = this.mockRepository.Create(); + var metadataLoadContext = this.mockRepository.Create(); + var assemblyShim = this.mockRepository.Create(); + var directoryTraverser = this.mockRepository.Create(); + var actualNugetUtilities = new DefaultNugetPackageUtilities(); + + nugetUtilities.Setup(n => n.FindAllNugetPackagesFiles(startingPath)).Returns(new[] { package }); + // Call actual implementation here + nugetUtilities.Setup(n => n.GetVersionFromPackageFile(It.IsAny())).Returns((s) => actualNugetUtilities.GetVersionFromPackageFile(s)); + // Call actual implementation here + nugetUtilities.Setup(n => n.GetPackageName(It.IsAny())).Returns((s) => actualNugetUtilities.GetPackageName(s)); + nugetUtilities.Setup(n => n.HasAlreadyBeenExtracted(It.IsAny())).Returns(false); + nugetUtilities.Setup(n => n.UnCompressNugetPackage(It.IsAny(), It.IsAny())).Verifiable(); + + directoryTraverser.Setup(d => d.TraverseDirectories($"{startingPath}/_extracted")).Returns(new[] { "pathy/mcpathface" }); + directoryTraverser.Setup(d => d.TraverseFiles(It.IsAny(), It.IsAny>())).Returns(new[] { "filey.mcfile.face" }); + + var contract = TestableTypeBuilder.New() + .WithName("IMyTestType") + .WithNamespace("Test.Type") + .Build(); + + var pluginAttributeTypedValue = new CustomAttributeTypedArgument(contract); + var pluginAttribute = new TestableAttribute + { + _AttributeType = typeof(Prise.Plugin.PluginAttribute), + _NamedArguments = new[]{new CustomAttributeNamedArgument(new TestableMemberInfo{ + _Name = "PluginType" + },pluginAttributeTypedValue)} + }; + + var testableType = TestableTypeBuilder.New() + .WithCustomAttributes(pluginAttribute) + .WithName("MyTestType") + .WithNamespace("Test.Type") + .Build(); + + assemblyShim.Setup(a => a.Types).Returns(new[] { testableType }); + + metadataLoadContext.Setup(c => c.LoadFromAssemblyName(It.IsAny())).Returns(assemblyShim.Object); + + var scanner = new DefaultNugetPackageAssemblyScanner( + (s) => metadataLoadContext.Object, + () => directoryTraverser.Object, + () => nugetUtilities.Object + ); + var types = await scanner.Scan(new AssemblyScannerOptions + { + StartingPath = startingPath, + PluginType = contract + }); + + var result = types.FirstOrDefault(); + Assert.IsNotNull(result); + Assert.AreEqual("MyTestType", result.PluginType.Name); + Assert.AreEqual("Test.Type", result.PluginType.Namespace); + } + + [TestMethod] + public async Task UnCompressed_NugetPackage_Does_Nothing() + { + var package = "Prise.Plugin.Package.1.0.0.nupkg"; + var startingPath = "/home/maarten"; + var nugetUtilities = this.mockRepository.Create(); + var metadataLoadContext = this.mockRepository.Create(); + var assemblyShim = this.mockRepository.Create(); + var directoryTraverser = this.mockRepository.Create(); + var actualNugetUtilities = new DefaultNugetPackageUtilities(); + + nugetUtilities.Setup(n => n.FindAllNugetPackagesFiles(startingPath)).Returns(new[] { package }); + // Call actual implementation here + nugetUtilities.Setup(n => n.GetVersionFromPackageFile(It.IsAny())).Returns((s) => actualNugetUtilities.GetVersionFromPackageFile(s)); + // Call actual implementation here + nugetUtilities.Setup(n => n.GetPackageName(It.IsAny())).Returns((s) => actualNugetUtilities.GetPackageName(s)); + nugetUtilities.Setup(n => n.HasAlreadyBeenExtracted(It.IsAny())).Returns(true); + + directoryTraverser.Setup(d => d.TraverseDirectories($"{startingPath}/_extracted")).Returns(new[] { "pathy/mcpathface" }); + directoryTraverser.Setup(d => d.TraverseFiles(It.IsAny(), It.IsAny>())).Returns(new[] { "filey.mcfile.face" }); + + var contract = TestableTypeBuilder.New() + .WithName("IMyTestType") + .WithNamespace("Test.Type") + .Build(); + + var pluginAttributeTypedValue = new CustomAttributeTypedArgument(contract); + var pluginAttribute = new TestableAttribute + { + _AttributeType = typeof(Prise.Plugin.PluginAttribute), + _NamedArguments = new[]{new CustomAttributeNamedArgument(new TestableMemberInfo{ + _Name = "PluginType" + },pluginAttributeTypedValue)} + }; + + var testableType = TestableTypeBuilder.New() + .WithCustomAttributes(pluginAttribute) + .WithName("MyTestType") + .WithNamespace("Test.Type") + .Build(); + + assemblyShim.Setup(a => a.Types).Returns(new[] { testableType }); + + metadataLoadContext.Setup(c => c.LoadFromAssemblyName(It.IsAny())).Returns(assemblyShim.Object); + + var scanner = new DefaultNugetPackageAssemblyScanner( + (s) => metadataLoadContext.Object, + () => directoryTraverser.Object, + () => nugetUtilities.Object + ); + var types = await scanner.Scan(new AssemblyScannerOptions + { + StartingPath = startingPath, + PluginType = contract + }); + + var result = types.FirstOrDefault(); + Assert.IsNotNull(result); + Assert.AreEqual("MyTestType", result.PluginType.Name); + Assert.AreEqual("Test.Type", result.PluginType.Namespace); + } + + [TestMethod] + public async Task Multiple_Versions_With_Current_Already_Extracted_Only_Extracts_Older() + { + var currentVersion = new Version("1.1.0"); + var package1 = "Prise.Plugin.Package.1.0.0.nupkg"; + var package2 = "Prise.Plugin.Package.1.1.0.nupkg"; + var startingPath = "/home/maarten"; + var nugetUtilities = this.mockRepository.Create(); + var metadataLoadContext = this.mockRepository.Create(); + var assemblyShim = this.mockRepository.Create(); + var directoryTraverser = this.mockRepository.Create(); + var actualNugetUtilities = new DefaultNugetPackageUtilities(); + + nugetUtilities.Setup(n => n.FindAllNugetPackagesFiles(startingPath)).Returns(new[] { package1, package2 }); + // Call actual implementation here + nugetUtilities.Setup(n => n.GetVersionFromPackageFile(It.IsAny())).Returns((s) => actualNugetUtilities.GetVersionFromPackageFile(s)); + // Call actual implementation here + nugetUtilities.Setup(n => n.GetPackageName(It.IsAny())).Returns((s) => actualNugetUtilities.GetPackageName(s)); + nugetUtilities.Setup(n => n.HasAlreadyBeenExtracted($"{startingPath}/_extracted/Prise.Plugin.Package/1.0.0")).Returns(false); + nugetUtilities.Setup(n => n.HasAlreadyBeenExtracted($"{startingPath}/_extracted/Prise.Plugin.Package/1.1.0")).Returns(true); + + nugetUtilities.Setup(n => n.UnCompressNugetPackage(It.IsAny(), $"{startingPath}/_extracted/Prise.Plugin.Package/1.0.0")).Verifiable(); + + directoryTraverser.Setup(d => d.TraverseDirectories($"{startingPath}/_extracted")).Returns(new[] { "pathy/mcpathface" }); + directoryTraverser.Setup(d => d.TraverseFiles(It.IsAny(), It.IsAny>())).Returns(new[] { "filey.mcfile.face" }); + + var contract = TestableTypeBuilder.New() + .WithName("IMyTestType") + .WithNamespace("Test.Type") + .Build(); + + var pluginAttributeTypedValue = new CustomAttributeTypedArgument(contract); + var pluginAttribute = new TestableAttribute + { + _AttributeType = typeof(Prise.Plugin.PluginAttribute), + _NamedArguments = new[]{new CustomAttributeNamedArgument(new TestableMemberInfo{ + _Name = "PluginType" + },pluginAttributeTypedValue)} + }; + + var testableType = TestableTypeBuilder.New() + .WithCustomAttributes(pluginAttribute) + .WithName("MyTestType") + .WithNamespace("Test.Type") + .Build(); + + assemblyShim.Setup(a => a.Types).Returns(new[] { testableType }); + + metadataLoadContext.Setup(c => c.LoadFromAssemblyName(It.IsAny())).Returns(assemblyShim.Object); + + var scanner = new DefaultNugetPackageAssemblyScanner( + (s) => metadataLoadContext.Object, + () => directoryTraverser.Object, + () => nugetUtilities.Object + ); + var types = await scanner.Scan(new AssemblyScannerOptions + { + StartingPath = startingPath, + PluginType = contract + }); + + var result = types.FirstOrDefault(); + Assert.IsNotNull(result); + Assert.AreEqual("MyTestType", result.PluginType.Name); + Assert.AreEqual("Test.Type", result.PluginType.Namespace); + } + + [TestMethod] + public async Task Scan_Succeeds() + { + var metadataLoadContext = this.mockRepository.Create(); + var assemblyShim = this.mockRepository.Create(); + var directoryTraverser = this.mockRepository.Create(); + var scanner = new DefaultAssemblyScanner( + (s) => metadataLoadContext.Object, + () => directoryTraverser.Object + ); + + directoryTraverser.Setup(d => d.TraverseDirectories(It.IsAny())).Returns(new[] { "pathy/mcpathface" }); + directoryTraverser.Setup(d => d.TraverseFiles(It.IsAny(), It.IsAny>())).Returns(new[] { "filey.mcfile.face" }); + + var contract = TestableTypeBuilder.New() + .WithName("IMyTestType") + .WithNamespace("Test.Type") + .Build(); + + var pluginAttributeTypedValue = new CustomAttributeTypedArgument(contract); + var pluginAttribute = new TestableAttribute + { + _AttributeType = typeof(Prise.Plugin.PluginAttribute), + _NamedArguments = new[]{new CustomAttributeNamedArgument(new TestableMemberInfo{ + _Name = "PluginType" + },pluginAttributeTypedValue)} + }; + + var testableType = TestableTypeBuilder.New() + .WithCustomAttributes(pluginAttribute) + .WithName("MyTestType") + .WithNamespace("Test.Type") + .Build(); + + assemblyShim.Setup(a => a.Types).Returns(new[] { testableType }); + + metadataLoadContext.Setup(c => c.LoadFromAssemblyName(It.IsAny())).Returns(assemblyShim.Object); + + var types = await scanner.Scan(new AssemblyScannerOptions + { + StartingPath = "/home/maarten", + PluginType = contract + }); + + var result = types.FirstOrDefault(); + Assert.IsNotNull(result); + Assert.AreEqual("MyTestType", result.PluginType.Name); + Assert.AreEqual("Test.Type", result.PluginType.Namespace); + } + } +} \ No newline at end of file diff --git a/Vendor/Prise.Tests/Caching/DefaultScopedPluginCacheTests.cs b/Vendor/Prise.Tests/Caching/DefaultScopedPluginCacheTests.cs new file mode 100644 index 0000000..a5d23dc --- /dev/null +++ b/Vendor/Prise.Tests/Caching/DefaultScopedPluginCacheTests.cs @@ -0,0 +1,41 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Moq; +using Prise.AssemblyScanning; +using Prise.Caching; +using Prise.Tests.Plugins; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Threading.Tasks; + +namespace Prise.Tests.Caching +{ + [TestClass] + public class DefaultScopedPluginCacheTests : TestBase + { + [TestMethod] + public void Ctor_Works() + { + Assert.IsNotNull(new DefaultScopedPluginCache()); + } + + [TestMethod] + public void Add_Works() + { + var assemblyShim = this.mockRepository.Create(); + var types = new List + { + typeof(DefaultScopedPluginCacheTests) + }; + var cache = new DefaultScopedPluginCache(); + cache.Add(assemblyShim.Object, types); + + var itemInCache = cache.GetAll().SingleOrDefault(); + Assert.IsNotNull(itemInCache); + Assert.AreEqual(assemblyShim.Object, itemInCache.AssemblyShim); + Assert.AreEqual(types.First(), itemInCache.HostTypes.First()); + } + } +} \ No newline at end of file diff --git a/Vendor/Prise.Tests/Core/DefaultPluginTypeSelectorTests.cs b/Vendor/Prise.Tests/Core/DefaultPluginTypeSelectorTests.cs new file mode 100644 index 0000000..1832b62 --- /dev/null +++ b/Vendor/Prise.Tests/Core/DefaultPluginTypeSelectorTests.cs @@ -0,0 +1,65 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Moq; +using Prise.AssemblyScanning; +using Prise.Caching; + +using Prise.Tests.Plugins; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Threading.Tasks; + +namespace Prise.Tests.Core +{ + [TestClass] + public class DefaultPluginTypeSelectorTests : TestBase + { + [TestMethod] + public void Ctor_Works() + { + Assert.IsNotNull(new DefaultPluginTypeSelector()); + } + + [TestMethod] + public void Selecting_Plugin_Types_Works() + { + var assemblyShim = this.mockRepository.Create(); + var contract = TestableTypeBuilder.New() + .WithName("IMyTestType") + .WithNamespace("Test.Type") + .Build(); + + var pluginAttributeTypedValue = new CustomAttributeTypedArgument(contract); + var pluginAttribute = new TestableAttribute + { + _AttributeType = typeof(Prise.Plugin.PluginAttribute), + _NamedArguments = new[]{new CustomAttributeNamedArgument(new TestableMemberInfo{ + _Name = "PluginType" + },pluginAttributeTypedValue)} + }; + + var testableType = TestableTypeBuilder.New() + .WithCustomAttributes(pluginAttribute) + .WithName("MyTestType") + .WithNamespace("Test.Type") + .Build(); + + var testableType2 = TestableTypeBuilder.New() + .WithCustomAttributes(pluginAttribute) + .WithName("MyTestType2") + .WithNamespace("Test.Type") + .Build(); + + assemblyShim.Setup(a => a.Types).Returns(new[] { testableType2, testableType, typeof(ITestPlugin) }); + + var selector = new DefaultPluginTypeSelector(); + var pluginsTypes = selector.SelectPluginTypes(contract, assemblyShim.Object); + + Assert.AreEqual(2, pluginsTypes.Count()); + Assert.AreEqual("MyTestType", pluginsTypes.First().Name); + Assert.AreEqual("MyTestType2", pluginsTypes.ElementAt(1).Name); + } + } +} \ No newline at end of file diff --git a/Vendor/Prise.Tests/IMyService.cs b/Vendor/Prise.Tests/IMyService.cs new file mode 100644 index 0000000..22ced56 --- /dev/null +++ b/Vendor/Prise.Tests/IMyService.cs @@ -0,0 +1,34 @@ +using System; +using System.Threading.Tasks; + +namespace Prise.Tests +{ + [System.Serializable] + public class MyServiceException : System.Exception + { + public MyServiceException() { } + public MyServiceException(string message) : base(message) { } + public MyServiceException(string message, System.Exception inner) : base(message, inner) { } + protected MyServiceException( + System.Runtime.Serialization.SerializationInfo info, + System.Runtime.Serialization.StreamingContext context) : base(info, context) { } + } + + public interface IMyService + { + Task GetString(); + void SetString(string value); + decimal Add(decimal a, decimal b); + decimal Add(decimal a, decimal b, decimal c); + decimal Subtract(decimal a, decimal b); + decimal Multiply(decimal a, decimal b); + decimal Divide(decimal a, decimal b); + Task DivideAsync(decimal a, decimal b); + Task ReadFromDisk(string file); + Task ReadFromDisk(string file, string addition); + string ThrowsMyServiceException(); + Task ThrowsMyServiceExceptionAsync(); + Task SetStringOverload(); + Task SetStringOverload(string value); + } +} diff --git a/Vendor/Prise.Tests/MyService.cs b/Vendor/Prise.Tests/MyService.cs new file mode 100644 index 0000000..0a490e7 --- /dev/null +++ b/Vendor/Prise.Tests/MyService.cs @@ -0,0 +1,51 @@ +using System; +using System.IO; +using System.Reflection; +using System.Threading.Tasks; + +namespace Prise.Tests +{ + public class MyService : IMyService + { + private string value = "Test"; + public decimal Add(decimal a, decimal b) => a + b; + public decimal Add(decimal a, decimal b, decimal c) => a + b + c; + public decimal Subtract(decimal a, decimal b) => a - b; + public decimal Multiply(decimal a, decimal b) => a * b; + public decimal Divide(decimal a, decimal b) => a / b; + public async Task DivideAsync(decimal a, decimal b) + { + await Task.Delay(100); + return a / b; + } + public Task ReadFromDisk(string file) => File.ReadAllTextAsync(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), file)); + public async Task ReadFromDisk(string file, string addition) + { + var content = await File.ReadAllTextAsync(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), file)); + return content + addition; + } + public Task GetString() => Task.FromResult(this.value); + public void SetString(string value) + { + this.value = value; + } + public string ThrowsMyServiceException() => throw new MyServiceException(value); + public Task ThrowsMyServiceExceptionAsync() + { + return Task.FromException(new MyServiceException(value)); + } + + public async Task SetStringOverload() + { + await Task.Delay(100); + this.value = $"{this.value} {this.value}"; + } + + public async Task SetStringOverload(string value) + { + await Task.Delay(100); + this.value = value; + return this.value; + } + } +} diff --git a/Vendor/Prise.Tests/Platform/DefaultRuntimePlatformContextTests.cs b/Vendor/Prise.Tests/Platform/DefaultRuntimePlatformContextTests.cs new file mode 100644 index 0000000..1ec949d --- /dev/null +++ b/Vendor/Prise.Tests/Platform/DefaultRuntimePlatformContextTests.cs @@ -0,0 +1,331 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Moq; +using Prise.AssemblyScanning; +using Prise.Caching; + +using Prise.Platform; +using Prise.Tests.Plugins; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Threading.Tasks; + +namespace Prise.Tests.Platform +{ + [TestClass] + public class DefaultRuntimePlatformContextTests : TestBase + { + [TestMethod] + public void Ctor_Throws_When_PlatformAbstraction_Null() + { + var exception = Assert.ThrowsException(() => new DefaultRuntimePlatformContext(null, null)); + exception.Message.Contains("platformAbstractionFactory"); + } + + [TestMethod] + public void Ctor_Throws_When_DirectoryTraverser_Null() + { + var exception = Assert.ThrowsException(() => new DefaultRuntimePlatformContext(() => null, null)); + exception.Message.Contains("directoryTraverserFactory"); + } + + [TestMethod] + public void Ctor_Works() + { + Assert.IsNotNull(new DefaultRuntimePlatformContext(() => null, () => null)); + } + + [TestMethod] + public void GetPlatformExtensions_NotSupported_Throws() + { + var platformAbstraction = this.mockRepository.Create(); + var directoryTraverser = this.mockRepository.Create(); + + platformAbstraction.Setup(p => p.IsWindows()).Returns(false); + platformAbstraction.Setup(p => p.IsLinux()).Returns(false); + platformAbstraction.Setup(p => p.IsOSX()).Returns(false); + + var context = new DefaultRuntimePlatformContext(() => platformAbstraction.Object, () => directoryTraverser.Object); + + Assert.ThrowsException(() => context.GetPlatformExtensions()); + } + + [TestMethod] + public void GetPlatformExtensions_Linux_Works() + { + var platformAbstraction = this.mockRepository.Create(); + var directoryTraverser = this.mockRepository.Create(); + + platformAbstraction.Setup(p => p.IsWindows()).Returns(false); + platformAbstraction.Setup(p => p.IsLinux()).Returns(true); + + var context = new DefaultRuntimePlatformContext(() => platformAbstraction.Object, () => directoryTraverser.Object); + var results = context.GetPlatformExtensions(); + Assert.AreEqual(2, results.Count()); + Assert.AreEqual(".so", results.First()); + Assert.AreEqual(".so.1", results.ElementAt(1)); + } + + [TestMethod] + public void GetPlatformExtensions_Windows_Works() + { + var platformAbstraction = this.mockRepository.Create(); + var directoryTraverser = this.mockRepository.Create(); + + platformAbstraction.Setup(p => p.IsWindows()).Returns(true); + + var context = new DefaultRuntimePlatformContext(() => platformAbstraction.Object, () => directoryTraverser.Object); + var results = context.GetPlatformExtensions(); + Assert.AreEqual(1, results.Count()); + Assert.AreEqual(".dll", results.First()); + } + + [TestMethod] + public void GetPlatformExtensions_OSX_Works() + { + var platformAbstraction = this.mockRepository.Create(); + var directoryTraverser = this.mockRepository.Create(); + + platformAbstraction.Setup(p => p.IsWindows()).Returns(false); + platformAbstraction.Setup(p => p.IsLinux()).Returns(false); + platformAbstraction.Setup(p => p.IsOSX()).Returns(true); + + var context = new DefaultRuntimePlatformContext(() => platformAbstraction.Object, () => directoryTraverser.Object); + var results = context.GetPlatformExtensions(); + Assert.AreEqual(1, results.Count()); + Assert.AreEqual(".dylib", results.First()); + } + + [TestMethod] + public void GetPluginDependencyNames_Works() + { + var platformAbstraction = this.mockRepository.Create(); + var directoryTraverser = this.mockRepository.Create(); + var context = new DefaultRuntimePlatformContext(() => platformAbstraction.Object, () => directoryTraverser.Object); + + var results = context.GetPluginDependencyNames("MyPlugin"); + Assert.AreEqual(4, results.Count()); + Assert.AreEqual("MyPlugin.dll", results.First()); + Assert.AreEqual("MyPlugin.ni.dll", results.ElementAt(1)); + Assert.AreEqual("MyPlugin.exe", results.ElementAt(2)); + Assert.AreEqual("MyPlugin.ni.exe", results.ElementAt(3)); + } + + [TestMethod] + public void GetPlatformDependencyNames_NotSupported_Throws() + { + var platformAbstraction = this.mockRepository.Create(); + var directoryTraverser = this.mockRepository.Create(); + + platformAbstraction.Setup(p => p.IsWindows()).Returns(false); + platformAbstraction.Setup(p => p.IsLinux()).Returns(false); + platformAbstraction.Setup(p => p.IsOSX()).Returns(false); + + var context = new DefaultRuntimePlatformContext(() => platformAbstraction.Object, () => directoryTraverser.Object); + + Assert.ThrowsException(() => context.GetPlatformDependencyNames("MyPlugin")); + } + + [TestMethod] + public void GetPlatformDependencyNames_Linux_Works() + { + var platformAbstraction = this.mockRepository.Create(); + var directoryTraverser = this.mockRepository.Create(); + + platformAbstraction.Setup(p => p.IsWindows()).Returns(false); + platformAbstraction.Setup(p => p.IsLinux()).Returns(true); + + var context = new DefaultRuntimePlatformContext(() => platformAbstraction.Object, () => directoryTraverser.Object); + var results = context.GetPlatformDependencyNames("MyPlugin"); + Assert.AreEqual(4, results.Count()); + Assert.AreEqual("MyPlugin.so", results.First()); + Assert.AreEqual("MyPlugin.so.1", results.ElementAt(1)); + Assert.AreEqual("libMyPlugin.so", results.ElementAt(2)); + Assert.AreEqual("libMyPlugin.so.1", results.ElementAt(3)); + } + + [TestMethod] + public void GetPlatformDependencyNames_Windows_Works() + { + var platformAbstraction = this.mockRepository.Create(); + var directoryTraverser = this.mockRepository.Create(); + + platformAbstraction.Setup(p => p.IsWindows()).Returns(true); + + var context = new DefaultRuntimePlatformContext(() => platformAbstraction.Object, () => directoryTraverser.Object); + var results = context.GetPlatformDependencyNames("MyPlugin"); + Assert.AreEqual(1, results.Count()); + Assert.AreEqual("MyPlugin.dll", results.First()); + } + + [TestMethod] + public void GetPlatformDependencyNames_OSX_Works() + { + var platformAbstraction = this.mockRepository.Create(); + var directoryTraverser = this.mockRepository.Create(); + + platformAbstraction.Setup(p => p.IsWindows()).Returns(false); + platformAbstraction.Setup(p => p.IsLinux()).Returns(false); + platformAbstraction.Setup(p => p.IsOSX()).Returns(true); + + var context = new DefaultRuntimePlatformContext(() => platformAbstraction.Object, () => directoryTraverser.Object); + var results = context.GetPlatformDependencyNames("MyPlugin"); + Assert.AreEqual(2, results.Count()); + Assert.AreEqual("MyPlugin.dylib", results.First()); + Assert.AreEqual("libMyPlugin.dylib", results.ElementAt(1)); + } + + + [TestMethod] + public void GetRuntimeInfo_NotSupported_Throws() + { + var platformAbstraction = this.mockRepository.Create(); + var directoryTraverser = this.mockRepository.Create(); + + platformAbstraction.Setup(p => p.IsWindows()).Returns(false); + platformAbstraction.Setup(p => p.IsLinux()).Returns(false); + platformAbstraction.Setup(p => p.IsOSX()).Returns(false); + + var context = new DefaultRuntimePlatformContext(() => platformAbstraction.Object, () => directoryTraverser.Object); + + Assert.ThrowsException(() => context.GetRuntimeInfo()); + } + + [TestMethod] + public void GetRuntimeInfo_Unknown_Runtime_Throws() + { + var platformAbstraction = this.mockRepository.Create(); + var directoryTraverser = this.mockRepository.Create(); + + var unknownPlatorm = "MICROSOFT.ASPNETNEW.APP"; + var platormDependendLocation = "/usr/share/dotnet/shared"; + + platformAbstraction.Setup(p => p.IsWindows()).Returns(false); + platformAbstraction.Setup(p => p.IsLinux()).Returns(true); + directoryTraverser.Setup(d => d.TraverseDirectories(platormDependendLocation)).Returns(new[] { $"{platormDependendLocation}/{unknownPlatorm}" }); + + var context = new DefaultRuntimePlatformContext(() => platformAbstraction.Object, () => directoryTraverser.Object); + + Assert.ThrowsException(() => context.GetRuntimeInfo()); + } + + [TestMethod] + public void GetRuntimeInfo_Linux_Works() + { + var platormDependendLocation = "/usr/share/dotnet/shared"; + var runtimes = new[]{ + $"{platormDependendLocation}/MICROSOFT.ASPNETCORE.ALL", + $"{platormDependendLocation}/MICROSOFT.ASPNETCORE.APP", + $"{platormDependendLocation}/MICROSOFT.NETCORE.APP", + }; + var versions = new[]{ + $"2.1.0", + $"3.1.0", + $"5.0.0", + $"6.0.0" + }; + var platformAbstraction = this.mockRepository.Create(); + var directoryTraverser = this.mockRepository.Create(); + + platformAbstraction.Setup(p => p.IsWindows()).Returns(false); + platformAbstraction.Setup(p => p.IsLinux()).Returns(true); + directoryTraverser.Setup(d => d.TraverseDirectories(platormDependendLocation)).Returns(runtimes); + directoryTraverser.Setup(d => d.TraverseDirectories(runtimes[0])).Returns(versions.Select(v => $"{runtimes[0]}/{v}")); + directoryTraverser.Setup(d => d.TraverseDirectories(runtimes[1])).Returns(versions.Select(v => $"{runtimes[1]}/{v}")); + directoryTraverser.Setup(d => d.TraverseDirectories(runtimes[2])).Returns(versions.Select(v => $"{runtimes[2]}/{v}")); + + var context = new DefaultRuntimePlatformContext(() => platformAbstraction.Object, () => directoryTraverser.Object); + var result = context.GetRuntimeInfo(); + + Assert.AreEqual(12, result.Runtimes.Count()); + Assert.AreEqual("2.1.0", result.Runtimes.ElementAt(0).Version); + Assert.AreEqual("3.1.0", result.Runtimes.ElementAt(1).Version); + Assert.AreEqual("5.0.0", result.Runtimes.ElementAt(2).Version); + Assert.AreEqual("6.0.0", result.Runtimes.ElementAt(3).Version); + Assert.AreEqual(RuntimeType.AspNetCoreAll, result.Runtimes.ElementAt(0).RuntimeType); + Assert.AreEqual(RuntimeType.AspNetCoreApp, result.Runtimes.ElementAt(4).RuntimeType); + Assert.AreEqual(RuntimeType.NetCoreApp, result.Runtimes.ElementAt(8).RuntimeType); + } + + [TestMethod] + public void GetRuntimeInfo_Windows_Works() + { + var platormDependendLocation = "C:\\Program Files\\dotnet\\shared"; + var runtimes = new[]{ + $"{platormDependendLocation}/MICROSOFT.ASPNETCORE.ALL", + $"{platormDependendLocation}/MICROSOFT.ASPNETCORE.APP", + $"{platormDependendLocation}/MICROSOFT.NETCORE.APP", + $"{platormDependendLocation}/MICROSOFT.WINDOWSDESKTOP.APP", + }; + var versions = new[]{ + $"2.1.0", + $"3.1.0", + $"5.0.0", + $"6.0.0" + }; + var platformAbstraction = this.mockRepository.Create(); + var directoryTraverser = this.mockRepository.Create(); + + platformAbstraction.Setup(p => p.IsWindows()).Returns(true); + directoryTraverser.Setup(d => d.TraverseDirectories(System.IO.Path.GetFullPath(platormDependendLocation))).Returns(runtimes); + directoryTraverser.Setup(d => d.TraverseDirectories(runtimes[0])).Returns(versions.Select(v => $"{runtimes[0]}/{v}")); + directoryTraverser.Setup(d => d.TraverseDirectories(runtimes[1])).Returns(versions.Select(v => $"{runtimes[1]}/{v}")); + directoryTraverser.Setup(d => d.TraverseDirectories(runtimes[2])).Returns(versions.Select(v => $"{runtimes[2]}/{v}")); + directoryTraverser.Setup(d => d.TraverseDirectories(runtimes[3])).Returns(versions.Select(v => $"{runtimes[3]}/{v}")); + + var context = new DefaultRuntimePlatformContext(() => platformAbstraction.Object, () => directoryTraverser.Object); + var result = context.GetRuntimeInfo(); + + Assert.AreEqual(16, result.Runtimes.Count()); + Assert.AreEqual("2.1.0", result.Runtimes.ElementAt(0).Version); + Assert.AreEqual("3.1.0", result.Runtimes.ElementAt(1).Version); + Assert.AreEqual("5.0.0", result.Runtimes.ElementAt(2).Version); + Assert.AreEqual("6.0.0", result.Runtimes.ElementAt(3).Version); + Assert.AreEqual(RuntimeType.AspNetCoreAll, result.Runtimes.ElementAt(0).RuntimeType); + Assert.AreEqual(RuntimeType.AspNetCoreApp, result.Runtimes.ElementAt(4).RuntimeType); + Assert.AreEqual(RuntimeType.NetCoreApp, result.Runtimes.ElementAt(8).RuntimeType); + Assert.AreEqual(RuntimeType.WindowsDesktopApp, result.Runtimes.ElementAt(12).RuntimeType); + } + + [TestMethod] + public void GetRuntimeInfo_OSX_Works() + { + var platormDependendLocation = "/usr/local/share/dotnet/shared"; + var runtimes = new[]{ + $"{platormDependendLocation}/MICROSOFT.ASPNETCORE.ALL", + $"{platormDependendLocation}/MICROSOFT.ASPNETCORE.APP", + $"{platormDependendLocation}/MICROSOFT.NETCORE.APP", + }; + var versions = new[]{ + $"2.1.0", + $"3.1.0", + $"5.0.0", + $"6.0.0" + }; + var platformAbstraction = this.mockRepository.Create(); + var directoryTraverser = this.mockRepository.Create(); + + platformAbstraction.Setup(p => p.IsWindows()).Returns(false); + platformAbstraction.Setup(p => p.IsLinux()).Returns(false); + platformAbstraction.Setup(p => p.IsOSX()).Returns(true); + directoryTraverser.Setup(d => d.TraverseDirectories(platormDependendLocation)).Returns(runtimes); + directoryTraverser.Setup(d => d.TraverseDirectories(runtimes[0])).Returns(versions.Select(v => $"{runtimes[0]}/{v}")); + directoryTraverser.Setup(d => d.TraverseDirectories(runtimes[1])).Returns(versions.Select(v => $"{runtimes[1]}/{v}")); + directoryTraverser.Setup(d => d.TraverseDirectories(runtimes[2])).Returns(versions.Select(v => $"{runtimes[2]}/{v}")); + + var context = new DefaultRuntimePlatformContext(() => platformAbstraction.Object, () => directoryTraverser.Object); + var result = context.GetRuntimeInfo(); + + Assert.AreEqual(12, result.Runtimes.Count()); + Assert.AreEqual("2.1.0", result.Runtimes.ElementAt(0).Version); + Assert.AreEqual("3.1.0", result.Runtimes.ElementAt(1).Version); + Assert.AreEqual("5.0.0", result.Runtimes.ElementAt(2).Version); + Assert.AreEqual("6.0.0", result.Runtimes.ElementAt(3).Version); + Assert.AreEqual(RuntimeType.AspNetCoreAll, result.Runtimes.ElementAt(0).RuntimeType); + Assert.AreEqual(RuntimeType.AspNetCoreApp, result.Runtimes.ElementAt(4).RuntimeType); + Assert.AreEqual(RuntimeType.NetCoreApp, result.Runtimes.ElementAt(8).RuntimeType); + } + } +} \ No newline at end of file diff --git a/Vendor/Prise.Tests/Plugins/ITestPlugin.cs b/Vendor/Prise.Tests/Plugins/ITestPlugin.cs new file mode 100644 index 0000000..e963543 --- /dev/null +++ b/Vendor/Prise.Tests/Plugins/ITestPlugin.cs @@ -0,0 +1,22 @@ +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace Prise.Tests.Plugins +{ + public class TestDto + { + public IEnumerable Children { get; set; } + public string Name { get; set; } + public int Number { get; set; } + } + + public interface ITestPlugin + { + Task GetStringAsync(); + TestDto Foo(TestDto dto); + IEnumerable Foos(IEnumerable dto); + Task Bar(TestDto dto); + Task> Bars(IEnumerable dto); + Task> GetData(string filter); + } +} \ No newline at end of file diff --git a/Vendor/Prise.Tests/Plugins/TestPluginA.cs b/Vendor/Prise.Tests/Plugins/TestPluginA.cs new file mode 100644 index 0000000..769708a --- /dev/null +++ b/Vendor/Prise.Tests/Plugins/TestPluginA.cs @@ -0,0 +1,41 @@ +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Prise.Plugin; + +namespace Prise.Tests.Plugins +{ + [Plugin(PluginType = typeof(ITestPlugin))] + public class TestPluginA : ITestPlugin + { + public Task Bar(TestDto dto) + { + return Task.FromResult(dto); + } + + public Task> Bars(IEnumerable dtos) + { + return Task.FromResult(dtos); + } + + public TestDto Foo(TestDto dto) + { + return dto; + } + + public IEnumerable Foos(IEnumerable dtos) + { + return dtos; + } + + public async Task> GetData(string filter) + { + return Enumerable.Empty(); + } + + public async Task GetStringAsync() + { + return "String"; + } + } +} \ No newline at end of file diff --git a/Vendor/Prise.Tests/Plugins/TestPluginActivation.cs b/Vendor/Prise.Tests/Plugins/TestPluginActivation.cs new file mode 100644 index 0000000..8f483f3 --- /dev/null +++ b/Vendor/Prise.Tests/Plugins/TestPluginActivation.cs @@ -0,0 +1,54 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using Prise.Plugin; + +namespace Prise.Tests.Plugins +{ + [Plugin(PluginType = typeof(ITestPlugin))] + public class TestPluginActivation : ITestPlugin + { + private List data; + + [PluginActivated] + public void Activated() + { + this.data = new List + { + new TestDto + { + Name = "TestPluginB Activated!" + } + }; + } + + public Task Bar(TestDto dto) + { + return Task.FromResult(dto); + } + + public Task> Bars(IEnumerable dtos) + { + return Task.FromResult(dtos); + } + + public TestDto Foo(TestDto dto) + { + return dto; + } + + public IEnumerable Foos(IEnumerable dtos) + { + return this.data; + } + + public async Task> GetData(string filter) + { + return this.data; + } + + public async Task GetStringAsync() + { + return "String"; + } + } +} \ No newline at end of file diff --git a/Vendor/Prise.Tests/Plugins/TestType.cs b/Vendor/Prise.Tests/Plugins/TestType.cs new file mode 100644 index 0000000..621fe44 --- /dev/null +++ b/Vendor/Prise.Tests/Plugins/TestType.cs @@ -0,0 +1,445 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Reflection; + +namespace Prise.Tests.Plugins +{ + public interface IBuilder + { + T Build(); + } + + public class TestableTypeBuilder : IBuilder + { + private string name; + private string @namespace; + private List attributes; + private List members; + private List methods; + private List fields; + public TestableTypeBuilder() + { + this.attributes = new List(); + this.members = new List(); + this.methods = new List(); + this.fields = new List(); + } + public TestableTypeBuilder WithCustomAttributes(params CustomAttributeData[] attributes) + { + this.attributes.AddRange(attributes); + return this; + } + + public TestableTypeBuilder WithMethods(params MethodInfo[] methods) + { + this.methods.AddRange(methods); + return this; + } + + public TestableTypeBuilder WithFields(params FieldInfo[] fields) + { + this.fields.AddRange(fields); + + return this; + } + + public TestableTypeBuilder WithName(string name) + { + this.name = name; + return this; + } + + public TestableTypeBuilder WithNamespace(string @namespace) + { + this.@namespace = @namespace; + return this; + } + + public TestableType Build() => new TestableType + { + _CustomAttributes = this.attributes, + _Name = this.name, + _Namespace = this.@namespace, + _Methods = this.methods, + _Fields = this.fields, + _Members = this.members + }; + + public static TestableTypeBuilder New() => new TestableTypeBuilder(); + } + + public class TestableAttributeBuilder : IBuilder + { + private Type attributeType; + private List arguments; + public TestableAttributeBuilder() + { + this.arguments = new List(); + } + + public TestableAttributeBuilder WithAttributeType(Type type) + { + this.attributeType = type; + return this; + } + + public TestableAttributeBuilder WithNamedAgrument(CustomAttributeNamedArgument argument) + { + this.arguments.Add(argument); + return this; + } + + public TestableAttributeBuilder WithNamedAgrument(string name, object value) + { + this.arguments.Add(new CustomAttributeNamedArgument(new TestableMemberInfo + { + _Name = name + }, new CustomAttributeTypedArgument(value))); + return this; + } + + public TestableAttribute Build() => new TestableAttribute + { + _AttributeType = this.attributeType, + _NamedArguments = this.arguments + }; + + public static TestableAttributeBuilder New() => new TestableAttributeBuilder(); + } + + public class TestableMethodInfoBuilder : IBuilder + { + private string name; + private List attributes; + public TestableMethodInfoBuilder() + { + this.attributes = new List(); + } + + public TestableMethodInfoBuilder WithName(string name) + { + this.name = name; + return this; + } + + public TestableMethodInfoBuilder WithAttribute(CustomAttributeData attribute) + { + this.attributes.Add(attribute); + return this; + } + + public TestableMethodInfo Build() => new TestableMethodInfo + { + _Name = this.name, + _CustomAttributes = this.attributes + }; + + public static TestableMethodInfoBuilder New() => new TestableMethodInfoBuilder(); + } + + public class TestableFieldBuilder : IBuilder + { + private string name; + private List attributes; + public TestableFieldBuilder() + { + this.attributes = new List(); + } + + public TestableFieldBuilder WithName(string name) + { + this.name = name; + return this; + } + + public TestableFieldBuilder WithAttribute(CustomAttributeData attribute) + { + this.attributes.Add(attribute); + return this; + } + + public TestableFieldInfo Build() => new TestableFieldInfo + { + _Name = this.name, + _CustomAttributes = this.attributes + }; + + public static TestableFieldBuilder New() => new TestableFieldBuilder(); + } + public class TestableAttribute : CustomAttributeData + { + internal Type _AttributeType; + internal IList _NamedArguments; + public override IList NamedArguments => _NamedArguments; + public override Type AttributeType => _AttributeType; + } + + public class TestableMemberInfo : MemberInfo + { + internal string _Name; + + public override IEnumerable CustomAttributes { get; } // TODO + + public override Type DeclaringType => throw new NotImplementedException(); + + public override MemberTypes MemberType => throw new NotImplementedException(); + + public override string Name => _Name; + + public override Type ReflectedType => throw new NotImplementedException(); + + public override object[] GetCustomAttributes(bool inherit) + { + throw new NotImplementedException(); + } + + public override object[] GetCustomAttributes(Type attributeType, bool inherit) + { + throw new NotImplementedException(); + } + + public override bool IsDefined(Type attributeType, bool inherit) + { + throw new NotImplementedException(); + } + } + + public class TestableMethodInfo : MethodInfo + { + internal string _Name; + internal IEnumerable _CustomAttributes; + public override IEnumerable CustomAttributes => _CustomAttributes; + public override ICustomAttributeProvider ReturnTypeCustomAttributes => throw new NotImplementedException(); + + public override MethodAttributes Attributes => throw new NotImplementedException(); + + public override RuntimeMethodHandle MethodHandle => throw new NotImplementedException(); + + public override Type DeclaringType => throw new NotImplementedException(); + + public override string Name => _Name; + + public override Type ReflectedType => throw new NotImplementedException(); + + public override MethodInfo GetBaseDefinition() + { + throw new NotImplementedException(); + } + + public override object[] GetCustomAttributes(bool inherit) => _CustomAttributes.ToArray(); + + public override object[] GetCustomAttributes(Type attributeType, bool inherit) => _CustomAttributes.ToArray(); + + public override MethodImplAttributes GetMethodImplementationFlags() + { + throw new NotImplementedException(); + } + + public override ParameterInfo[] GetParameters() + { + throw new NotImplementedException(); + } + + public override object Invoke(object obj, BindingFlags invokeAttr, Binder binder, object[] parameters, CultureInfo culture) + { + throw new NotImplementedException(); + } + + public override bool IsDefined(Type attributeType, bool inherit) + { + throw new NotImplementedException(); + } + } + + public class TestableFieldInfo : FieldInfo + { + internal IEnumerable _CustomAttributes; + internal string _Name; + public override IEnumerable CustomAttributes => _CustomAttributes; + + public override FieldAttributes Attributes => throw new NotImplementedException(); + + public override RuntimeFieldHandle FieldHandle => throw new NotImplementedException(); + + public override Type FieldType => throw new NotImplementedException(); + + public override Type DeclaringType => throw new NotImplementedException(); + + public override string Name => _Name; + + public override Type ReflectedType => throw new NotImplementedException(); + + public override object[] GetCustomAttributes(bool inherit) => _CustomAttributes.ToArray(); + public override object[] GetCustomAttributes(Type attributeType, bool inherit) => _CustomAttributes.ToArray(); + + public override object GetValue(object obj) + { + throw new NotImplementedException(); + } + + public override bool IsDefined(Type attributeType, bool inherit) + { + throw new NotImplementedException(); + } + + public override void SetValue(object obj, object value, BindingFlags invokeAttr, Binder binder, CultureInfo culture) + { + throw new NotImplementedException(); + } + } + + public class TestableType : TypeInfo + { + internal IEnumerable _CustomAttributes; + internal string _Name; + internal string _Namespace; + internal IEnumerable _Members; + internal IEnumerable _Methods; + internal IEnumerable _Fields; + + public override IEnumerable DeclaredFields => _Fields; + + public override IEnumerable CustomAttributes => _CustomAttributes; + + public override Assembly Assembly => throw new NotImplementedException(); + + public override string AssemblyQualifiedName => throw new NotImplementedException(); + + public override Type BaseType => throw new NotImplementedException(); + + public override string FullName => throw new NotImplementedException(); + + public override Guid GUID => throw new NotImplementedException(); + + public override Module Module => throw new NotImplementedException(); + + public override string Namespace => _Namespace; + public override Type UnderlyingSystemType => throw new NotImplementedException(); + + public override string Name => _Name; + + public override ConstructorInfo[] GetConstructors(BindingFlags bindingAttr) + { + throw new NotImplementedException(); + } + + public override object[] GetCustomAttributes(bool inherit) => _CustomAttributes.ToArray(); + + public override object[] GetCustomAttributes(Type attributeType, bool inherit) => _CustomAttributes.ToArray(); + + public override Type GetElementType() + { + throw new NotImplementedException(); + } + + public override EventInfo GetEvent(string name, BindingFlags bindingAttr) + { + throw new NotImplementedException(); + } + + public override EventInfo[] GetEvents(BindingFlags bindingAttr) + { + throw new NotImplementedException(); + } + + public override FieldInfo GetField(string name, BindingFlags bindingAttr) + { + throw new NotImplementedException(); + } + + public override FieldInfo[] GetFields(BindingFlags bindingAttr) + { + throw new NotImplementedException(); + } + + public override Type GetInterface(string name, bool ignoreCase) + { + throw new NotImplementedException(); + } + + public override Type[] GetInterfaces() + { + throw new NotImplementedException(); + } + + public override MemberInfo[] GetMembers(BindingFlags bindingAttr) => _Members.ToArray(); + + public override MethodInfo[] GetMethods(BindingFlags bindingAttr) => _Methods.ToArray(); + public override Type GetNestedType(string name, BindingFlags bindingAttr) + { + throw new NotImplementedException(); + } + + public override Type[] GetNestedTypes(BindingFlags bindingAttr) + { + throw new NotImplementedException(); + } + + public override PropertyInfo[] GetProperties(BindingFlags bindingAttr) + { + throw new NotImplementedException(); + } + + public override object InvokeMember(string name, BindingFlags invokeAttr, Binder binder, object target, object[] args, ParameterModifier[] modifiers, CultureInfo culture, string[] namedParameters) + { + throw new NotImplementedException(); + } + + public override bool IsDefined(Type attributeType, bool inherit) + { + throw new NotImplementedException(); + } + + protected override TypeAttributes GetAttributeFlagsImpl() + { + throw new NotImplementedException(); + } + + protected override ConstructorInfo GetConstructorImpl(BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers) + { + throw new NotImplementedException(); + } + + protected override MethodInfo GetMethodImpl(string name, BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers) + { + throw new NotImplementedException(); + } + + protected override PropertyInfo GetPropertyImpl(string name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers) + { + throw new NotImplementedException(); + } + + protected override bool HasElementTypeImpl() + { + throw new NotImplementedException(); + } + + protected override bool IsArrayImpl() + { + throw new NotImplementedException(); + } + + protected override bool IsByRefImpl() + { + throw new NotImplementedException(); + } + + protected override bool IsCOMObjectImpl() + { + throw new NotImplementedException(); + } + + protected override bool IsPointerImpl() + { + throw new NotImplementedException(); + } + + protected override bool IsPrimitiveImpl() + { + throw new NotImplementedException(); + } + } +} \ No newline at end of file diff --git a/Vendor/Prise.Tests/Prise.Tests.csproj b/Vendor/Prise.Tests/Prise.Tests.csproj new file mode 100644 index 0000000..4ce3e81 --- /dev/null +++ b/Vendor/Prise.Tests/Prise.Tests.csproj @@ -0,0 +1,35 @@ + + + + net6.0 + + false + + + + + + + + + + + + + + + + + + + + Always + + + Always + + + Always + + + diff --git a/Vendor/Prise.Tests/Proxy/ProxyTests.cs b/Vendor/Prise.Tests/Proxy/ProxyTests.cs new file mode 100644 index 0000000..5924061 --- /dev/null +++ b/Vendor/Prise.Tests/Proxy/ProxyTests.cs @@ -0,0 +1,20 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Threading.Tasks; + +namespace Prise.Tests +{ + [TestClass] + public class ProxyTests : TestBase + { + [TestMethod] + public async Task InvokingProxyWorks() + { + var originalObject = new MyService(); + + var proxy = Prise.Proxy.ProxyCreator.CreateProxy(originalObject); + var result = await proxy.GetString(); + + Assert.AreEqual("Test", result); + } + } +} diff --git a/Vendor/Prise.Tests/ReverseProxy/MyServiceProxy.cs b/Vendor/Prise.Tests/ReverseProxy/MyServiceProxy.cs new file mode 100644 index 0000000..c318b83 --- /dev/null +++ b/Vendor/Prise.Tests/ReverseProxy/MyServiceProxy.cs @@ -0,0 +1,32 @@ +using System; +using System.Reflection; +using System.Threading.Tasks; + +namespace Prise.Tests +{ + public class MyServiceProxyParameterMismatch : MyServiceProxy + { + public MyServiceProxyParameterMismatch(object hostService) : base(hostService) { } + public override Task SetStringOverload(string value) => this.InvokeOnHostService>(); //Parameter mismatch + + } + public class MyServiceProxy : Prise.Proxy.ReverseProxy, IMyService + { + public MyServiceProxy(object hostService) : base(hostService) { } + + public virtual decimal Add(decimal a, decimal b) => this.InvokeOnHostService(a, b); + public virtual decimal Add(decimal a, decimal b, decimal c) => this.InvokeOnHostService(a, b, c); + public virtual decimal Subtract(decimal a, decimal b) => this.InvokeOnHostService(a, b); + public virtual decimal Multiply(decimal a, decimal b) => this.InvokeOnHostService(a, b); + public virtual decimal Divide(decimal a, decimal b) => this.InvokeOnHostService(a, b); + public virtual Task DivideAsync(decimal a, decimal b) => this.InvokeOnHostService>(a, b); + public virtual Task ReadFromDisk(string file) => this.InvokeOnHostService>(file); + public virtual Task ReadFromDisk(string file, string addition) => this.InvokeOnHostService>(file, addition); + public virtual Task GetString() => this.InvokeOnHostService>(); + public virtual void SetString(string value) => this.InvokeOnHostService(value); + public virtual string ThrowsMyServiceException() => this.InvokeOnHostService(); + public virtual Task ThrowsMyServiceExceptionAsync() => this.InvokeOnHostService>(); + public virtual Task SetStringOverload() => this.InvokeOnHostService(); + public virtual Task SetStringOverload(string value) => this.InvokeOnHostService>(value); + } +} diff --git a/Vendor/Prise.Tests/ReverseProxy/ReverseProxyTests.cs b/Vendor/Prise.Tests/ReverseProxy/ReverseProxyTests.cs new file mode 100644 index 0000000..935482f --- /dev/null +++ b/Vendor/Prise.Tests/ReverseProxy/ReverseProxyTests.cs @@ -0,0 +1,157 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Prise.Proxy; +using System; +using System.IO; +using System.Threading.Tasks; + +namespace Prise.Tests +{ + [TestClass] + public class ReverseProxyTests : TestBase + { + [TestMethod] + public async Task InvokingGetStringWorks() + { + var result = await GetSut().GetString(); + + Assert.AreEqual("Test", result); + } + + [TestMethod] + public async Task InvokingSetStringWorks() + { + var sut = GetSut(); + sut.SetString("A string"); + var result = await sut.GetString(); + + Assert.AreEqual("A string", result); + } + + [TestMethod] + public async Task InvokingAddWorks() + { + var result = GetSut().Add(33.33m, 100); + + Assert.AreEqual(133.33m, result); + } + + [TestMethod] + public async Task InvokingAddOverloadingWorks() + { + var result = GetSut().Add(33.33m, 100, 33.33m); + + Assert.AreEqual(166.66m, result); + } + + [TestMethod] + public async Task InvokingSubtractWorks() + { + var result = GetSut().Subtract(33.33m, 100m); + + Assert.AreEqual(-66.67m, result); + } + + [TestMethod] + public async Task InvokingMultiplyWorks() + { + var result = GetSut().Multiply(20, 50); + + Assert.AreEqual(1000, result); + } + + [TestMethod] + public async Task InvokingDivideWorks() + { + var result = GetSut().Divide(40.40m, 2); + + Assert.AreEqual(20.20m, result); + } + + [TestMethod] + public async Task InvokingDivideAsyncWorks() + { + var result = await GetSut().DivideAsync(40.40m, 2); + + Assert.AreEqual(20.20m, result); + } + + [TestMethod] + public async Task InvokingDivideThrowsException() + { + Assert.ThrowsException(() => GetSut().Divide(1000m, 0)); + } + + [TestMethod] + public async Task InvokingDivideAsyncThrowsException() + { + var exception = await Assert.ThrowsExceptionAsync(() => GetSut().DivideAsync(1000m, 0)); + Assert.IsInstanceOfType(exception.InnerException, typeof(DivideByZeroException)); + } + + [TestMethod] + public async Task InvokingThrowsMyServiceExceptionWorks() + { + Assert.ThrowsException(() => GetSut().ThrowsMyServiceException()); + } + + [TestMethod] + public async Task InvokingThrowsMyServiceExceptionAsyncWorks() + { + var exception = await Assert.ThrowsExceptionAsync(async () => await GetSut().ThrowsMyServiceExceptionAsync()); + Assert.IsInstanceOfType(exception.InnerException, typeof(MyServiceException)); + } + + [TestMethod] + public async Task ReadFromDiskWorks() + { + Assert.AreEqual("This is content from a test file", await GetSut().ReadFromDisk("TestFile.txt")); + } + + [TestMethod] + public async Task ReadFromDiskThrowsFileNotFoundException() + { + var exception = await Assert.ThrowsExceptionAsync(() => GetSut().ReadFromDisk("NOTFOUND.txt")); + Assert.IsInstanceOfType(exception.InnerException, typeof(FileNotFoundException)); + } + + [TestMethod] + public async Task InvokingSetStringOverloadWorks() + { + var sut = GetSut(); + sut.SetString("A string"); + await sut.SetStringOverload(); + var result = await sut.GetString(); + + Assert.AreEqual("A string A string", result); + } + + [TestMethod] + public async Task InvokingSetStringOverloadWithValueWorks() + { + var value = "MyValue"; + var result = await GetSut().SetStringOverload(value); + + Assert.AreEqual("MyValue", value); + } + + [TestMethod] + public async Task InvokingSetStringOverloadWithWrongParametersThrowsReverseProxyException() + { + var sut = new MyServiceProxyParameterMismatch(new MyService()); + await Assert.ThrowsExceptionAsync(async () => await sut.SetStringOverload("value")); + } + + [TestMethod] + public async Task InvokingSetStringOverloadWithValueAndInheritanceWorks() + { + var sut = new MyServiceProxyParameterMismatch(new MyService()); + sut.SetString("A string"); + await sut.SetStringOverload(); + var result = await sut.GetString(); + + Assert.AreEqual("A string A string", result); + } + + private IMyService GetSut() => new MyServiceProxy(new MyService()); + } +} diff --git a/Vendor/Prise.Tests/TestBase.cs b/Vendor/Prise.Tests/TestBase.cs new file mode 100644 index 0000000..b230f95 --- /dev/null +++ b/Vendor/Prise.Tests/TestBase.cs @@ -0,0 +1,28 @@ +using System.IO; +using System.Reflection; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Moq; + +namespace Prise.Tests +{ + public abstract class TestBase + { + protected MockRepository mockRepository; + + public TestBase() + { + this.mockRepository = new MockRepository(MockBehavior.Strict); + } + + protected string GetPathToAssemblies() + { + return Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Assemblies"); + } + + [TestCleanup()] + public void Cleanup() + { + this.mockRepository.VerifyAll(); + } + } +} \ No newline at end of file diff --git a/Vendor/Prise.Tests/TestContext.cs b/Vendor/Prise.Tests/TestContext.cs new file mode 100644 index 0000000..ee04a56 --- /dev/null +++ b/Vendor/Prise.Tests/TestContext.cs @@ -0,0 +1,40 @@ +using Moq; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; + +namespace Prise.Tests +{ + public class TestContext + where T : class + { + private readonly T sut; + private readonly List mocks; + + public TestContext(T sut, params Mock[] mocks) + { + this.mocks = new List(); + + foreach (var mock in mocks) + { + this.mocks.Add(mock); + } + + this.sut = sut; + + } + + public T Sut() => this.sut; + + public Mock GetMock() + where M : class + { + var mock = this.mocks.FirstOrDefault(m => m.Object.GetType().GetTypeInfo().ImplementedInterfaces.ElementAt(0) == typeof(M)); + if (mock == null) + throw new NotSupportedException($"Mock {typeof(M).Name} not found"); + + return mock.As(); + } + } +} \ No newline at end of file diff --git a/Vendor/Prise.Tests/TestData.json b/Vendor/Prise.Tests/TestData.json new file mode 100644 index 0000000..8c18251 --- /dev/null +++ b/Vendor/Prise.Tests/TestData.json @@ -0,0 +1,34 @@ +{ + "testData": [ + { + "name": "First", + "number": 1 + }, + { + "name": "Second", + "number": 2 + }, + { + "name": "Third", + "number": 3 + }, + { + "name": "FourthWithChildren", + "number": 4, + "children": [ + { + "name": "4.First", + "number": 1 + }, + { + "name": "4.Second", + "number": 2 + }, + { + "name": "4.Third", + "number": 3 + } + ] + } + ] +} diff --git a/Vendor/Prise.Tests/TestFile.txt b/Vendor/Prise.Tests/TestFile.txt new file mode 100644 index 0000000..1aeabe9 --- /dev/null +++ b/Vendor/Prise.Tests/TestFile.txt @@ -0,0 +1 @@ +This is content from a test file \ No newline at end of file diff --git a/Vendor/Prise/Activation/DefaultPluginActivationContext.cs b/Vendor/Prise/Activation/DefaultPluginActivationContext.cs new file mode 100644 index 0000000..081299c --- /dev/null +++ b/Vendor/Prise/Activation/DefaultPluginActivationContext.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Reflection; + +namespace Prise.Activation +{ + public class DefaultPluginActivationContext : IPluginActivationContext + { + public IAssemblyShim PluginAssembly { get; set; } + public Type PluginType { get; set; } + public Type PluginBootstrapperType { get; set; } + public MethodInfo PluginFactoryMethod { get; set; } + public MethodInfo PluginActivatedMethod { get; set; } + public IEnumerable PluginServices { get; set; } + public IEnumerable BootstrapperServices { get; set; } + } +} \ No newline at end of file diff --git a/Vendor/Prise/Activation/DefaultPluginActivationContextProvider.cs b/Vendor/Prise/Activation/DefaultPluginActivationContextProvider.cs new file mode 100644 index 0000000..394b883 --- /dev/null +++ b/Vendor/Prise/Activation/DefaultPluginActivationContextProvider.cs @@ -0,0 +1,131 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using Prise.Plugin; + +namespace Prise.Activation +{ + public class DefaultPluginActivationContextProvider : IPluginActivationContextProvider + { + public IPluginActivationContext ProvideActivationContext(Type remoteType, IAssemblyShim pluginAssembly) + { + var bootstrapper = pluginAssembly + .Types + .FirstOrDefault(t => t.CustomAttributes + .Any(c => c.AttributeType.Name == typeof(Prise.Plugin.PluginBootstrapperAttribute).Name && + (c.NamedArguments.First(a => a.MemberName == "PluginType").TypedValue.Value as Type).Name == remoteType.Name)); + + // TODO End support for PluginFactories by next major release + var factoryMethod = remoteType.GetMethods() + .FirstOrDefault(m => m.CustomAttributes + .Any(c => c.AttributeType.Name == typeof(Prise.Plugin.PluginFactoryAttribute).Name)); + + var pluginServices = new List(); + var typeInfo = remoteType as System.Reflection.TypeInfo; + + var pluginServiceFields = GetFieldsOfCustomAttribute(typeInfo, typeof(Prise.Plugin.PluginServiceAttribute).Name); + if (pluginServiceFields.Any()) + pluginServices = pluginServiceFields.Select(f => ParsePluginService(remoteType, f)).ToList(); + + var bootstrapperServices = new List(); + if (bootstrapper != null) + { + var bootstrapperServiceFields = GetFieldsOfCustomAttribute(bootstrapper as System.Reflection.TypeInfo, typeof(Prise.Plugin.BootstrapperServiceAttribute).Name); + if (bootstrapperServiceFields.Any()) + bootstrapperServices = bootstrapperServiceFields.Select(f => ParseBootstrapperService(bootstrapper, f)).ToList(); + } + + var pluginActivatedMethod = GetPluginActivatedMethod(remoteType); + + return new DefaultPluginActivationContext + { + PluginType = remoteType, + PluginAssembly = pluginAssembly, + PluginBootstrapperType = bootstrapper, + PluginFactoryMethod = factoryMethod, + PluginActivatedMethod = pluginActivatedMethod, + PluginServices = pluginServices, + BootstrapperServices = bootstrapperServices, + }; + } + + private static MethodInfo GetPluginActivatedMethod(Type type) + { + var pluginActivatedMethods = type.GetMethods(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public) + .Where(m => m.CustomAttributes.Any(c => c.AttributeType.Name == typeof(Prise.Plugin.PluginActivatedAttribute).Name)); + + if (pluginActivatedMethods.Count() > 1) + throw new PluginActivationException($"Type {type.Name} contains multiple PluginActivated methods, please provide only one private void OnActivated(){{}} method and annotate it with the PluginActivated Attribute."); + + return pluginActivatedMethods.FirstOrDefault(); + } + + private static IEnumerable GetFieldsOfCustomAttribute(TypeInfo type, string typeName) + { + return type.DeclaredFields + .Where(f => f.CustomAttributes.Any(c => c.AttributeType.Name == typeName)); + } + + private static PluginService ParsePluginService(Type remoteType, FieldInfo field) + { + var attribute = field.CustomAttributes.First(c => c.AttributeType.Name == typeof(Prise.Plugin.PluginServiceAttribute).Name); + var serviceTypeArg = attribute.NamedArguments.FirstOrDefault(a => a.MemberName == "ServiceType"); + if (serviceTypeArg == null) + throw new PluginActivationException($"The ServiceType {remoteType.Name} argument is required for the {nameof(PluginServiceAttribute)}."); + + var serviceType = serviceTypeArg.TypedValue.Value as Type; + + ProvidedBy providedBy = default(ProvidedBy); + var providedByArg = attribute.NamedArguments.FirstOrDefault(a => a.MemberName == "ProvidedBy"); + if (providedByArg != null) + { + var providedByArgValue = providedByArg.TypedValue.Value; + if (providedByArgValue != null) + providedBy = (ProvidedBy)(int)providedByArgValue; + } + + Type proxyType = GetProxyTypeFromAttribute(attribute); + + return new PluginService + { + ProvidedBy = providedBy, + ServiceType = serviceType, + FieldName = field.Name, + ProxyType = proxyType + }; + } + + private static BootstrapperService ParseBootstrapperService(Type remoteType, FieldInfo field) + { + var attribute = field.CustomAttributes.First(c => c.AttributeType.Name == typeof(Prise.Plugin.BootstrapperServiceAttribute).Name); + var serviceTypeArg = attribute.NamedArguments.FirstOrDefault(a => a.MemberName == "ServiceType"); + if (serviceTypeArg == null) + throw new PluginActivationException($"The ServiceType {remoteType.Name} argument is required for the {nameof(BootstrapperServiceAttribute)}."); + + var serviceType = serviceTypeArg.TypedValue.Value as Type; + + Type proxyType = GetProxyTypeFromAttribute(attribute); + + return new BootstrapperService + { + ServiceType = serviceType, + FieldName = field.Name, + ProxyType = proxyType + }; + } + + private static Type GetProxyTypeFromAttribute(CustomAttributeData attribute) + { + Type proxyType = null; + var proxyTypeArg = attribute.NamedArguments.FirstOrDefault(a => a.MemberName == "ProxyType"); + if (proxyTypeArg.TypedValue.Value == null) // TODO End support of BridgeType by next major release + proxyTypeArg = attribute.NamedArguments.FirstOrDefault(a => a.MemberName == "BridgeType"); + + if (proxyTypeArg.TypedValue.Value != null) + proxyType = proxyTypeArg.TypedValue.Value as Type; + + return proxyType; + } + } +} \ No newline at end of file diff --git a/Vendor/Prise/Activation/DefaultPluginActivationOptions.cs b/Vendor/Prise/Activation/DefaultPluginActivationOptions.cs new file mode 100644 index 0000000..9809530 --- /dev/null +++ b/Vendor/Prise/Activation/DefaultPluginActivationOptions.cs @@ -0,0 +1,15 @@ +using System; +using Microsoft.Extensions.DependencyInjection; +using Prise.Proxy; + +namespace Prise.Activation +{ + public class DefaultPluginActivationOptions : IPluginActivationOptions + { + public IAssemblyShim PluginAssembly { get; set; } + public Type PluginType { get; set; } + public IServiceCollection HostServices { get; set; } + public IParameterConverter ParameterConverter { get; set; } + public IResultConverter ResultConverter { get; set; } + } +} \ No newline at end of file diff --git a/Vendor/Prise/Activation/DefaultPluginActivator.cs b/Vendor/Prise/Activation/DefaultPluginActivator.cs new file mode 100644 index 0000000..e66eee6 --- /dev/null +++ b/Vendor/Prise/Activation/DefaultPluginActivator.cs @@ -0,0 +1,90 @@ +using System; +using System.Collections.Concurrent; +using System.Threading.Tasks; +using Prise.Plugin; +using Prise.Utils; + +namespace Prise.Activation +{ + public class DefaultPluginActivator : IPluginActivator, IDisposable + { + protected ConcurrentBag disposables; + protected IPluginActivationContextProvider pluginActivationContextProvider; + protected IRemotePluginActivator remotePluginActivator; + protected IPluginProxyCreator proxyCreator; + + public DefaultPluginActivator( + Func pluginActivationContextProviderFactory, + Func remotePluginActivatorFactory, + Func proxyCreatorFactory) + { + this.disposables = new ConcurrentBag(); + this.pluginActivationContextProvider = pluginActivationContextProviderFactory.ThrowIfNull(nameof(pluginActivationContextProviderFactory))(); + this.remotePluginActivator = remotePluginActivatorFactory.ThrowIfNull(nameof(remotePluginActivatorFactory))(); + this.proxyCreator = proxyCreatorFactory.ThrowIfNull(nameof(proxyCreatorFactory))(); + } + + public Task ActivatePlugin(IPluginActivationOptions pluginActivationOptions) + { + if (pluginActivationOptions.PluginAssembly == null) + throw new ArgumentNullException($"{nameof(IPluginActivationOptions)}.{nameof(pluginActivationOptions.PluginAssembly)}"); + if (pluginActivationOptions.PluginType == null) + throw new ArgumentNullException($"{nameof(IPluginActivationOptions)}.{nameof(pluginActivationOptions.PluginType)}"); + if (pluginActivationOptions.ParameterConverter == null) + throw new ArgumentNullException($"{nameof(IPluginActivationOptions)}.{nameof(pluginActivationOptions.ParameterConverter)}"); + if (pluginActivationOptions.ResultConverter == null) + throw new ArgumentNullException($"{nameof(IPluginActivationOptions)}.{nameof(pluginActivationOptions.ResultConverter)}"); + + T pluginProxy = default(T); + IPluginBootstrapper bootstrapperProxy = null; + + var pluginActivationContext = this.pluginActivationContextProvider.ProvideActivationContext(pluginActivationOptions.PluginType, pluginActivationOptions.PluginAssembly); + + if (pluginActivationContext.PluginBootstrapperType != null) + { + var remoteBootstrapperInstance = this.remotePluginActivator.CreateRemoteBootstrapper(pluginActivationContext, pluginActivationOptions.HostServices); + + var remoteBootstrapperProxy = this.proxyCreator.CreateBootstrapperProxy(remoteBootstrapperInstance); + + this.disposables.Add(remoteBootstrapperProxy as IDisposable); + bootstrapperProxy = remoteBootstrapperProxy; + } + + var remoteObject = this.remotePluginActivator.CreateRemoteInstance( + pluginActivationContext, + bootstrapperProxy, + pluginActivationOptions.HostServices + ); + + pluginProxy = this.proxyCreator.CreatePluginProxy(remoteObject, pluginActivationOptions.ParameterConverter, pluginActivationOptions.ResultConverter); + + this.disposables.Add(pluginProxy as IDisposable); + + return Task.FromResult(pluginProxy); + } + + private bool disposed = false; + protected virtual void Dispose(bool disposing) + { + if (!this.disposed && disposing) + { + this.remotePluginActivator?.Dispose(); + this.proxyCreator?.Dispose(); + + foreach (var disposable in this.disposables) + disposable.Dispose(); + + this.remotePluginActivator = null; + this.proxyCreator = null; + this.disposables = null; + } + this.disposed = true; + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + } +} \ No newline at end of file diff --git a/Vendor/Prise/Activation/DefaultPluginProxyCreator.cs b/Vendor/Prise/Activation/DefaultPluginProxyCreator.cs new file mode 100644 index 0000000..b715947 --- /dev/null +++ b/Vendor/Prise/Activation/DefaultPluginProxyCreator.cs @@ -0,0 +1,31 @@ +using System; +using Prise.Plugin; +using Prise.Proxy; + +namespace Prise.Activation +{ + public class DefaultPluginProxyCreator : IPluginProxyCreator + { + public IPluginBootstrapper CreateBootstrapperProxy(object remoteBootstrapper) => + ProxyCreator.CreateProxy(remoteBootstrapper); + + public T CreatePluginProxy(object remoteObject, IParameterConverter parameterConverter, IResultConverter resultConverter) => + ProxyCreator.CreateProxy(remoteObject, parameterConverter, resultConverter); + + protected bool disposed = false; + protected virtual void Dispose(bool disposing) + { + if (!this.disposed && disposing) + { + // Nothing to do here + } + this.disposed = true; + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + } +} \ No newline at end of file diff --git a/Vendor/Prise/Activation/DefaultPluginServiceProvider.cs b/Vendor/Prise/Activation/DefaultPluginServiceProvider.cs new file mode 100644 index 0000000..c7613ef --- /dev/null +++ b/Vendor/Prise/Activation/DefaultPluginServiceProvider.cs @@ -0,0 +1,116 @@ +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Linq; +using Prise.Utils; + +namespace Prise.Activation +{ + public class DefaultBootstrapperServiceProvider : IBootstrapperServiceProvider + { + protected IServiceProvider localProvider; + protected IEnumerable hostTypes; + protected ConcurrentBag instances; + + public DefaultBootstrapperServiceProvider(IServiceProvider localProvider, IEnumerable hostTypes) + { + this.localProvider = localProvider.ThrowIfNull(nameof(localProvider)); + this.hostTypes = hostTypes.ThrowIfNull(nameof(hostTypes)); + this.instances = new ConcurrentBag(); + } + + public virtual object GetHostService(Type type) + { + var hostType = this.hostTypes.FirstOrDefault(t => t.Name == type.Name); + if (hostType == null) + throw new PluginActivationException($"An instance of type {type.Name} is required to activate this plugin, but it was not registered as a Host Type, please configure this type via the UseHostServices, ConfigureHostServices or ConfigureSharedServices builder method."); + + var instance = this.localProvider.GetService(hostType); + if (instance == null) + throw new PluginActivationException($"An instance of Host Service type {type.Name} could not be properly constructed (null)."); + + this.instances.Add(instance); + return instance; + } + + protected bool disposed = false; + protected virtual void Dispose(bool disposing) + { + if (!this.disposed && disposing) + { + foreach (var instance in this.instances) + (instance as IDisposable)?.Dispose(); + + this.instances.Clear(); + + this.instances = null; + this.localProvider = null; + this.hostTypes = null; + } + this.disposed = true; + } + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + } + + public class DefaultPluginServiceProvider : DefaultBootstrapperServiceProvider, IPluginServiceProvider + { + private IEnumerable pluginTypes; + + public DefaultPluginServiceProvider(IServiceProvider localProvider, IEnumerable hostTypes, IEnumerable pluginTypes) + : base(localProvider, hostTypes) + { + this.pluginTypes = pluginTypes; + } + + public object GetPluginService(Type type) + { + // Plugin services are registered via a PluginBootstrapper, eventually they'll land inside the localProvider. + var pluginType = this.pluginTypes.FirstOrDefault(t => t.Name == type.Name); + if (pluginType == null) + throw new PluginActivationException($"An instance of type {type.Name} is required to activate this plugin, but it was not registered as a Plugin Type, please provide this service via a PluginBootstrapper builder."); + + var instance = this.localProvider.GetService(type); + if (instance == null) + throw new PluginActivationException($"An instance of Plugin Service type {type.Name} could not be properly constructed (null)."); + + this.instances.Add(instance); + return instance; + } + + public override object GetHostService(Type type) + { + // Host services are provided by the Host. + var hostType = this.hostTypes.FirstOrDefault(t => t.Name == type.Name); + if (hostType == null) + throw new PluginActivationException($"An instance of type {type.Name} is required to activate this plugin, but it was not registered as a Host Type, please configure this type via the UseHostServices, ConfigureHostServices or ConfigureSharedServices builder method."); + + var instance = this.localProvider.GetService(hostType); + if (instance == null) + throw new PluginActivationException($"An instance of Host Service type {type.Name} could not be properly constructed (null)."); + + this.instances.Add(instance); + return instance; + } + + protected override void Dispose(bool disposing) + { + if (!this.disposed && disposing) + { + foreach (var instance in this.instances) + (instance as IDisposable)?.Dispose(); + + this.instances.Clear(); + + this.instances = null; + this.localProvider = null; + this.hostTypes = null; + this.pluginTypes = null; + } + this.disposed = true; + } + } +} \ No newline at end of file diff --git a/Vendor/Prise/Activation/DefaultRemotePluginActivator.cs b/Vendor/Prise/Activation/DefaultRemotePluginActivator.cs new file mode 100644 index 0000000..e7360ef --- /dev/null +++ b/Vendor/Prise/Activation/DefaultRemotePluginActivator.cs @@ -0,0 +1,242 @@ +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using Microsoft.Extensions.DependencyInjection; +using Prise.Plugin; +using Prise.Utils; + +namespace Prise.Activation +{ + public class DefaultRemotePluginActivator : IRemotePluginActivator + { + private Func, IBootstrapperServiceProvider> bootstrapperServiceProviderFactory; + private Func, IEnumerable, IPluginServiceProvider> pluginServiceProviderFactory; + private ConcurrentBag instances; + + public DefaultRemotePluginActivator(Func, IBootstrapperServiceProvider> bootstrapperServiceProviderFactory, + Func, IEnumerable, IPluginServiceProvider> pluginServiceProviderFactory) + { + this.bootstrapperServiceProviderFactory = bootstrapperServiceProviderFactory.ThrowIfNull(nameof(bootstrapperServiceProviderFactory)); + this.pluginServiceProviderFactory = pluginServiceProviderFactory.ThrowIfNull(nameof(pluginServiceProviderFactory)); + this.instances = new ConcurrentBag(); + } + + private object AddToDisposables(object obj) + { + this.instances.Add(obj); + return obj; + } + + public virtual object CreateRemoteBootstrapper(IPluginActivationContext pluginActivationContext, IServiceCollection hostServices = null) + { + var bootstrapperType = pluginActivationContext.PluginBootstrapperType; + var assembly = pluginActivationContext.PluginAssembly.Assembly; + var bootstrapperServices = pluginActivationContext.BootstrapperServices; + + var contructors = bootstrapperType.GetConstructors(BindingFlags.Public | BindingFlags.Instance); + var firstCtor = contructors.First(); + + if (!contructors.Any()) + throw new PluginActivationException($"No public constructors found for remote bootstrapper {bootstrapperType.Name}"); + if (firstCtor.GetParameters().Any()) + throw new PluginActivationException($"Bootstrapper {bootstrapperType.Name} must contain a public parameterless constructor"); + var bootstrapperInstance = assembly.CreateInstance(bootstrapperType.FullName); + var serviceProvider = AddToDisposables(GetServiceProviderForBootstrapper(new ServiceCollection(), hostServices ?? new ServiceCollection())) as IServiceProvider; + var bootstrapperServiceProvider = AddToDisposables(serviceProvider.GetService()) as IBootstrapperServiceProvider; + + bootstrapperInstance = InjectBootstrapperFieldsWithServices(bootstrapperInstance, bootstrapperServiceProvider, bootstrapperServices); + + return AddToDisposables(bootstrapperInstance); + } + + public virtual object CreateRemoteInstance(IPluginActivationContext pluginActivationContext, IPluginBootstrapper bootstrapper = null, IServiceCollection hostServices = null) + { + var pluginType = pluginActivationContext.PluginType; + var pluginAssembly = pluginActivationContext.PluginAssembly; + var factoryMethod = pluginActivationContext.PluginFactoryMethod; + + var contructors = pluginType.GetConstructors(BindingFlags.Public | BindingFlags.Instance); + + if (contructors.Count() > 1) + throw new PluginActivationException($"Multiple public constructors found for remote plugin {pluginType.Name}"); + + var serviceProvider = AddToDisposables(GetServiceProviderForPlugin(new ServiceCollection(), bootstrapper, hostServices ?? new ServiceCollection())) as IServiceProvider; + + if (factoryMethod != null) + return AddToDisposables(factoryMethod.Invoke(null, new[] { serviceProvider })); + + var firstCtor = contructors.FirstOrDefault(); + if (firstCtor != null && !firstCtor.GetParameters().Any()) // Empty default CTOR + { + var pluginServiceProvider = AddToDisposables(serviceProvider.GetService()) as IPluginServiceProvider; + var remoteInstance = pluginAssembly.Assembly.CreateInstance(pluginType.FullName); + remoteInstance = InjectPluginFieldsWithServices(remoteInstance, pluginServiceProvider, pluginActivationContext.PluginServices); + + ActivateIfNecessary(remoteInstance, pluginActivationContext); + + return AddToDisposables(remoteInstance); + } + + throw new PluginActivationException($"Plugin of type {pluginType.Name} could not be activated."); + } + + protected virtual void ActivateIfNecessary(object remoteInstance, IPluginActivationContext pluginActivationContext) + { + var pluginType = pluginActivationContext.PluginType; + if (pluginActivationContext.PluginActivatedMethod == null) + return; + + var remoteActivationMethod = remoteInstance.GetType().GetRuntimeMethods().FirstOrDefault(m => m.Name == pluginActivationContext.PluginActivatedMethod.Name); + if (remoteActivationMethod == null) + throw new PluginActivationException($"Remote activation method {pluginActivationContext.PluginActivatedMethod.Name} not found for plugin {pluginType.Name} on remote object {remoteInstance.GetType().Name}"); + + remoteActivationMethod.Invoke(remoteInstance, null); + } + + protected virtual object InjectBootstrapperFieldsWithServices(object remoteInstance, + IBootstrapperServiceProvider bootstrapperServiceProvider, + IEnumerable bootstrapperServices) + { + foreach (var bootstrapperService in bootstrapperServices) + { + var fieldName = bootstrapperService.FieldName; + var serviceInstance = bootstrapperServiceProvider.GetHostService(bootstrapperService.ServiceType); + + if (bootstrapperService.ProxyType == null) + throw new PluginActivationException($"Field {fieldName} requires a ProxyType (BridgeType)."); + + var reverseProxyCtor = GetReverseProxyConstructor(bootstrapperService.ProxyType); + if (reverseProxyCtor == null) + throw new PluginActivationException($"ReverseProxy {bootstrapperService.ProxyType.Name} must have a single public constructor with one parameter of type object."); + + var reverseProxyInstance = AddToDisposables(reverseProxyCtor.Invoke(new[] { serviceInstance })); + if (!TrySetField(remoteInstance, fieldName, reverseProxyInstance)) + throw new PluginActivationException($"Field {bootstrapperService.FieldName} on Plugin could not be set."); + } + + return remoteInstance; + } + + protected virtual object InjectPluginFieldsWithServices(object remoteInstance, + IPluginServiceProvider pluginServiceProvider, + IEnumerable pluginServices) + { + foreach (var pluginService in pluginServices) + { + var fieldName = pluginService.FieldName; + object serviceInstance = null; + switch (pluginService.ProvidedBy) + { + case ProvidedBy.Host: + serviceInstance = pluginServiceProvider.GetHostService(pluginService.ServiceType); + break; + case ProvidedBy.Plugin: + serviceInstance = pluginServiceProvider.GetPluginService(pluginService.ServiceType); + break; + } + + if (TrySetField(remoteInstance, fieldName, serviceInstance)) + continue; // Field was set successfully, continueing + + if (pluginService.ProxyType == null) + throw new PluginActivationException($"Field {pluginService.FieldName} could not be set, please consider using a ReverseProxy."); + + var reverseProxyCtor = GetReverseProxyConstructor(pluginService.ProxyType); + if (reverseProxyCtor == null) + throw new PluginActivationException($"ReverseProxy {pluginService.ProxyType.Name} must have a single public constructor with one parameter of type object."); + + var reverseProxyInstance = AddToDisposables(reverseProxyCtor.Invoke(new[] { serviceInstance })); + if (!TrySetField(remoteInstance, fieldName, reverseProxyInstance)) + throw new PluginActivationException($"Field {pluginService.FieldName} on Plugin could not be set."); + } + + return remoteInstance; + } + + protected virtual IServiceProvider GetServiceProviderForBootstrapper(IServiceCollection services, IServiceCollection hostServices) + { + foreach (var service in hostServices) + services.Add(service); + + services.AddScoped(sp => this.bootstrapperServiceProviderFactory( + sp, + hostServices.Select(d => d.ServiceType) + )); + + return services.BuildServiceProvider(); + } + + protected virtual IServiceProvider GetServiceProviderForPlugin(IServiceCollection services, IPluginBootstrapper bootstrapper, IServiceCollection hostServices) + { + // Add all the host services to the main collection + foreach (var service in hostServices) + services.Add(service); + + IServiceCollection pluginServices = new ServiceCollection(); + // If a bootstrapper was provided, add the services for the plugin to a new collection + if (bootstrapper != null) + pluginServices = bootstrapper.Bootstrap(pluginServices); + + // Add all the plugin services to the main collection + foreach (var service in pluginServices) + services.Add(service); + + services.AddScoped(sp => this.pluginServiceProviderFactory( + sp, + hostServices.Select(d => d.ServiceType), + pluginServices.Select(d => d.ServiceType) + )); + + return services.BuildServiceProvider(); + } + + protected virtual ConstructorInfo GetReverseProxyConstructor(Type proxyType) + { + return proxyType + .GetConstructors(BindingFlags.Public | BindingFlags.Instance) + .FirstOrDefault(c => c.GetParameters().Count() == 1 && c.GetParameters().First().ParameterType == typeof(object)); + } + + protected virtual bool TrySetField(object remoteInstance, string fieldName, object fieldInstance) + { + try + { + remoteInstance + .GetType() + .GetTypeInfo() + .DeclaredFields + .First(f => f.Name == fieldName) + .SetValue(remoteInstance, fieldInstance); + return true; + } + catch (ArgumentException) { } + return false; + } + + + private bool disposed = false; + protected virtual void Dispose(bool disposing) + { + if (!this.disposed && disposing) + { + foreach (var disposable in this.instances) + { + if (disposable as IDisposable != null) + (disposable as IDisposable)?.Dispose(); + } + instances.Clear(); + + this.instances = null; + } + this.disposed = true; + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + } +} \ No newline at end of file diff --git a/Vendor/Prise/Activation/IPluginActivationContext.cs b/Vendor/Prise/Activation/IPluginActivationContext.cs new file mode 100644 index 0000000..0023df8 --- /dev/null +++ b/Vendor/Prise/Activation/IPluginActivationContext.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Reflection; + +namespace Prise.Activation +{ + public interface IPluginActivationContext + { + IAssemblyShim PluginAssembly { get; } + Type PluginType { get; } + Type PluginBootstrapperType { get; } + MethodInfo PluginFactoryMethod { get; } + MethodInfo PluginActivatedMethod { get; } + IEnumerable PluginServices { get; } + IEnumerable BootstrapperServices { get; } + } +} \ No newline at end of file diff --git a/Vendor/Prise/Activation/IPluginActivationContextProvider.cs b/Vendor/Prise/Activation/IPluginActivationContextProvider.cs new file mode 100644 index 0000000..fe3a7e0 --- /dev/null +++ b/Vendor/Prise/Activation/IPluginActivationContextProvider.cs @@ -0,0 +1,9 @@ +using System; + +namespace Prise.Activation +{ + public interface IPluginActivationContextProvider + { + IPluginActivationContext ProvideActivationContext(Type remoteType, IAssemblyShim pluginAssembly); + } +} \ No newline at end of file diff --git a/Vendor/Prise/Activation/IPluginActivationOptions.cs b/Vendor/Prise/Activation/IPluginActivationOptions.cs new file mode 100644 index 0000000..fe627ac --- /dev/null +++ b/Vendor/Prise/Activation/IPluginActivationOptions.cs @@ -0,0 +1,15 @@ +using System; +using Microsoft.Extensions.DependencyInjection; +using Prise.Proxy; + +namespace Prise.Activation +{ + public interface IPluginActivationOptions + { + IAssemblyShim PluginAssembly { get; } + Type PluginType { get; } + IServiceCollection HostServices { get; } + IParameterConverter ParameterConverter { get; } + IResultConverter ResultConverter { get; } + } +} \ No newline at end of file diff --git a/Vendor/Prise/Activation/IPluginActivator.cs b/Vendor/Prise/Activation/IPluginActivator.cs new file mode 100644 index 0000000..66b2a82 --- /dev/null +++ b/Vendor/Prise/Activation/IPluginActivator.cs @@ -0,0 +1,10 @@ +using System; +using System.Threading.Tasks; + +namespace Prise.Activation +{ + public interface IPluginActivator: IDisposable + { + Task ActivatePlugin(IPluginActivationOptions pluginActivationMetaData); + } +} \ No newline at end of file diff --git a/Vendor/Prise/Activation/IPluginProxyCreator.cs b/Vendor/Prise/Activation/IPluginProxyCreator.cs new file mode 100644 index 0000000..ba1918a --- /dev/null +++ b/Vendor/Prise/Activation/IPluginProxyCreator.cs @@ -0,0 +1,12 @@ +using System; +using Prise.Plugin; +using Prise.Proxy; + +namespace Prise.Activation +{ + public interface IPluginProxyCreator : IDisposable + { + IPluginBootstrapper CreateBootstrapperProxy(object remoteBootstrapper); + T CreatePluginProxy(object remoteObject, IParameterConverter parameterConverter, IResultConverter resultConverter); + } +} \ No newline at end of file diff --git a/Vendor/Prise/Activation/IPluginServiceProvider.cs b/Vendor/Prise/Activation/IPluginServiceProvider.cs new file mode 100644 index 0000000..62ac565 --- /dev/null +++ b/Vendor/Prise/Activation/IPluginServiceProvider.cs @@ -0,0 +1,14 @@ +using System; + +namespace Prise.Activation +{ + public interface IBootstrapperServiceProvider : IDisposable + { + object GetHostService(Type type); + } + + public interface IPluginServiceProvider : IBootstrapperServiceProvider + { + object GetPluginService(Type type); + } +} \ No newline at end of file diff --git a/Vendor/Prise/Activation/IRemotePluginActivator.cs b/Vendor/Prise/Activation/IRemotePluginActivator.cs new file mode 100644 index 0000000..8dd64f5 --- /dev/null +++ b/Vendor/Prise/Activation/IRemotePluginActivator.cs @@ -0,0 +1,12 @@ +using System; +using Microsoft.Extensions.DependencyInjection; +using Prise.Plugin; + +namespace Prise.Activation +{ + public interface IRemotePluginActivator : IDisposable + { + object CreateRemoteBootstrapper(IPluginActivationContext pluginActivationContext, IServiceCollection hostServices = null); + object CreateRemoteInstance(IPluginActivationContext pluginActivationContext, IPluginBootstrapper bootstrapper = null, IServiceCollection hostServices = null); + } +} \ No newline at end of file diff --git a/Vendor/Prise/Activation/PluginActivationException.cs b/Vendor/Prise/Activation/PluginActivationException.cs new file mode 100644 index 0000000..d0df39e --- /dev/null +++ b/Vendor/Prise/Activation/PluginActivationException.cs @@ -0,0 +1,25 @@ +using System; +using System.Runtime.Serialization; + +namespace Prise.Activation +{ + [Serializable] + public class PluginActivationException : Exception + { + public PluginActivationException(string message) : base(message) + { + } + + public PluginActivationException(string message, Exception innerException) : base(message, innerException) + { + } + + public PluginActivationException() + { + } + + protected PluginActivationException(SerializationInfo info, StreamingContext context) : base(info, context) + { + } + } +} \ No newline at end of file diff --git a/Vendor/Prise/Activation/PluginService.cs b/Vendor/Prise/Activation/PluginService.cs new file mode 100644 index 0000000..c4844a1 --- /dev/null +++ b/Vendor/Prise/Activation/PluginService.cs @@ -0,0 +1,17 @@ +using System; +using Prise.Plugin; + +namespace Prise.Activation +{ + public class BootstrapperService + { + public string FieldName { get; set; } + public Type ServiceType { get; set; } + public Type ProxyType { get; set; } + } + + public class PluginService : BootstrapperService + { + public ProvidedBy ProvidedBy { get; set; } + } +} \ No newline at end of file diff --git a/Vendor/Prise/AssemblyLoading/AssemblyFromStrategy.cs b/Vendor/Prise/AssemblyLoading/AssemblyFromStrategy.cs new file mode 100644 index 0000000..742285f --- /dev/null +++ b/Vendor/Prise/AssemblyLoading/AssemblyFromStrategy.cs @@ -0,0 +1,13 @@ +using System.Reflection; + +namespace Prise.AssemblyLoading +{ + public class AssemblyFromStrategy + { + public Assembly Assembly { get; set; } + public bool CanBeReleased { get; set; } + + public static AssemblyFromStrategy Releasable(Assembly assembly) => new AssemblyFromStrategy() { Assembly = assembly, CanBeReleased = true }; + public static AssemblyFromStrategy NotReleasable(Assembly assembly) => new AssemblyFromStrategy() { Assembly = assembly, CanBeReleased = false }; + } +} \ No newline at end of file diff --git a/Vendor/Prise/AssemblyLoading/AssemblyLoadException.cs b/Vendor/Prise/AssemblyLoading/AssemblyLoadException.cs new file mode 100644 index 0000000..afe6fda --- /dev/null +++ b/Vendor/Prise/AssemblyLoading/AssemblyLoadException.cs @@ -0,0 +1,25 @@ +using System; +using System.Runtime.Serialization; + +namespace Prise.AssemblyLoading +{ + [Serializable] + public class AssemblyLoadingException : Exception + { + public AssemblyLoadingException(string message) : base(message) + { + } + + public AssemblyLoadingException(string message, Exception innerException) : base(message, innerException) + { + } + + public AssemblyLoadingException() + { + } + + protected AssemblyLoadingException(SerializationInfo info, StreamingContext context) : base(info, context) + { + } + } +} \ No newline at end of file diff --git a/Vendor/Prise/AssemblyLoading/DefaultAssemblyDependencyResolver.cs b/Vendor/Prise/AssemblyLoading/DefaultAssemblyDependencyResolver.cs new file mode 100644 index 0000000..d3f9e8a --- /dev/null +++ b/Vendor/Prise/AssemblyLoading/DefaultAssemblyDependencyResolver.cs @@ -0,0 +1,53 @@ +using System.Reflection; +#if HAS_NATIVE_RESOLVER +using System.Runtime.Loader; +using System.IO; +#endif + +namespace Prise.AssemblyLoading +{ + public class DefaultAssemblyDependencyResolver : IAssemblyDependencyResolver + { +#if HAS_NATIVE_RESOLVER + protected AssemblyDependencyResolver resolver; +#endif + + public DefaultAssemblyDependencyResolver(string fullPathToPluginAssembly) + { +#if HAS_NATIVE_RESOLVER + try + { + this.resolver = new AssemblyDependencyResolver(fullPathToPluginAssembly); + } + catch (System.ArgumentException ex) + { + throw new AssemblyLoadingException($"{nameof(AssemblyDependencyResolver)} could not be instantiated, possible issue with {fullPathToPluginAssembly} {Path.GetFileNameWithoutExtension(fullPathToPluginAssembly)}.deps.json file?", ex); + } +#endif + } + + public string ResolveAssemblyToPath(AssemblyName assemblyName) + { +#if HAS_NATIVE_RESOLVER + return this.resolver.ResolveAssemblyToPath(assemblyName); +#endif + return null; // Not supported + } + + public string ResolveUnmanagedDllToPath(string unmanagedDllName) + { +#if HAS_NATIVE_RESOLVER + + return this.resolver.ResolveUnmanagedDllToPath(unmanagedDllName); +#endif + return null; // Not supported + } + + public void Dispose() + { +#if HAS_NATIVE_RESOLVER + this.resolver= null; +#endif + } + } +} \ No newline at end of file diff --git a/Vendor/Prise/AssemblyLoading/DefaultAssemblyLoadContext.cs b/Vendor/Prise/AssemblyLoading/DefaultAssemblyLoadContext.cs new file mode 100644 index 0000000..a4888fe --- /dev/null +++ b/Vendor/Prise/AssemblyLoading/DefaultAssemblyLoadContext.cs @@ -0,0 +1,380 @@ +using System; +using System.Collections.Concurrent; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Threading.Tasks; + +using Prise.Utils; + +namespace Prise.AssemblyLoading +{ + public class DefaultAssemblyLoadContext : InMemoryAssemblyLoadContext, IAssemblyLoadContext + { + private readonly IServiceProvider serviceProvider; + protected IAssemblyDependencyResolver resolver; + protected ConcurrentDictionary loadedNativeLibraries; + protected ConcurrentBag loadedPlugins; + protected ConcurrentBag assemblyReferences; + protected INativeAssemblyUnloader nativeAssemblyUnloader; + protected IAssemblyLoadStrategy assemblyLoadStrategy; + protected IPluginDependencyContext pluginDependencyContext; + protected IPluginDependencyResolver pluginDependencyResolver; + protected NativeDependencyLoadPreference nativeDependencyLoadPreference; + protected string fullPathToPluginAssembly; + protected string initialPluginLoadDirectory; + protected PluginPlatformVersion pluginPlatformVersion; + protected Func pluginDependencyResolverFactory; + protected Func assemblyLoadStrategyFactory; + protected Func assemblyDependencyResolverFactory; + protected IFileSystemUtilities fileSystemUtilities; + protected IRuntimeDefaultAssemblyContext runtimeDefaultAssemblyLoadContext; + protected IPluginDependencyContextProvider pluginDependencyContextProvider; + + public DefaultAssemblyLoadContext(Func nativeAssemblyUnloaderFactory, + Func pluginDependencyResolverFactory, + Func assemblyLoadStrategyFactory, + Func assemblyDependencyResolverFactory, + Func fileSystemUtilitiesFactory, + Func runtimeDefaultAssemblyLoadContextFactory, + Func pluginDependencyContextProviderFactory) + { + this.nativeAssemblyUnloader = nativeAssemblyUnloaderFactory.ThrowIfNull(nameof(nativeAssemblyUnloaderFactory))(); + this.pluginDependencyResolverFactory = pluginDependencyResolverFactory.ThrowIfNull(nameof(pluginDependencyResolverFactory)); + this.assemblyLoadStrategyFactory = assemblyLoadStrategyFactory.ThrowIfNull(nameof(assemblyLoadStrategyFactory)); + this.assemblyDependencyResolverFactory = assemblyDependencyResolverFactory.ThrowIfNull(nameof(assemblyDependencyResolverFactory)); + this.fileSystemUtilities = fileSystemUtilitiesFactory.ThrowIfNull(nameof(fileSystemUtilitiesFactory))(); + this.runtimeDefaultAssemblyLoadContext = runtimeDefaultAssemblyLoadContextFactory.ThrowIfNull(nameof(runtimeDefaultAssemblyLoadContextFactory))(); + this.pluginDependencyContextProvider = pluginDependencyContextProviderFactory.ThrowIfNull(nameof(pluginDependencyContextProviderFactory))(); + this.loadedNativeLibraries = new ConcurrentDictionary(); + this.loadedPlugins = new ConcurrentBag(); + this.assemblyReferences = new ConcurrentBag(); + } + + private void GuardIfAlreadyLoaded(string pluginAssemblyName) + { + if (this.disposed || this.disposing) + throw new AssemblyLoadingException($"Cannot load Plugin {pluginAssemblyName} when disposed."); + + if (String.IsNullOrEmpty(pluginAssemblyName)) + throw new AssemblyLoadingException($"Cannot load empty Plugin. {nameof(pluginAssemblyName)} was null or empty."); + + if (this.loadedPlugins.Contains(pluginAssemblyName)) + throw new AssemblyLoadingException($"Plugin {pluginAssemblyName} was already loaded."); + + this.loadedPlugins.Add(pluginAssemblyName); + } + + public async Task LoadPluginAssembly(IPluginLoadContext pluginLoadContext) + { + if (pluginLoadContext == null) + throw new ArgumentNullException(nameof(pluginLoadContext)); + + var fullPathToAssembly = pluginLoadContext.FullPathToPluginAssembly.ThrowIfNullOrEmpty(nameof(pluginLoadContext.FullPathToPluginAssembly)); + + if (!Path.IsPathRooted(fullPathToAssembly)) + throw new AssemblyLoadingException($"FullPathToPluginAssembly {pluginLoadContext.FullPathToPluginAssembly} is not rooted, this must be a absolute path!"); + + this.fullPathToPluginAssembly = pluginLoadContext.FullPathToPluginAssembly; + this.initialPluginLoadDirectory = Path.GetDirectoryName(fullPathToPluginAssembly); + this.nativeDependencyLoadPreference = pluginLoadContext.NativeDependencyLoadPreference; + + GuardIfAlreadyLoaded(fullPathToPluginAssembly); + + this.resolver = this.assemblyDependencyResolverFactory(fullPathToPluginAssembly); + this.pluginDependencyContext = await this.pluginDependencyContextProvider.FromPluginLoadContext(pluginLoadContext); + this.pluginDependencyResolver = this.pluginDependencyResolverFactory(); + this.assemblyLoadStrategy = this.assemblyLoadStrategyFactory(); + this.pluginPlatformVersion = pluginLoadContext.PluginPlatformVersion ?? PluginPlatformVersion.Empty(); + + var ensuredPath = this.fileSystemUtilities.EnsureFileExists(fullPathToPluginAssembly); + + using (var pluginStream = await this.fileSystemUtilities.ReadFileFromDisk(ensuredPath)) + { + return new PriseAssembly(LoadAndAddToWeakReferences(pluginStream)); + } + } + + protected override Assembly Load(AssemblyName assemblyName) + { + // This fixes the issue where the ALC is still alive and utilized in the host + if (this.disposed || this.disposing) + return null; + + return LoadAndAddToWeakReferences(assemblyLoadStrategy.LoadAssembly( + this.initialPluginLoadDirectory, + assemblyName, + this.pluginDependencyContext, + LoadFromDependencyContext, + LoadFromRemote, + LoadFromDefaultContext + )); + } + + protected virtual bool IsResourceAssembly(AssemblyName assemblyName) + { + return !string.IsNullOrEmpty(assemblyName.CultureName) && !string.Equals("neutral", assemblyName.CultureName); + } + + // + /// This override includes the netcore 3.0 resolver + /// + /// + /// + protected ValueOrProceed LoadFromDependencyContext(string initialPluginLoadDirectory, AssemblyName assemblyName) + { + var assemblyPath = this.resolver.ResolveAssemblyToPath(assemblyName); + if (!String.IsNullOrEmpty(assemblyPath) && this.fileSystemUtilities.DoesFileExist(assemblyPath)) + { + return ValueOrProceed.FromValue(AssemblyFromStrategy.Releasable(LoadFromAssemblyPath(assemblyPath)), false); + } + + if (IsResourceAssembly(assemblyName)) + { + foreach (var resourceDependency in this.pluginDependencyContext.PluginResourceDependencies) + { + var resourcePath = Path.Combine(resourceDependency.Path, assemblyName.CultureName, assemblyName.Name + ".dll"); + if (this.fileSystemUtilities.DoesFileExist(resourcePath)) + { + return ValueOrProceed.FromValue(AssemblyFromStrategy.Releasable(LoadFromAssemblyPath(resourcePath)), false); + } + } + + // Do not proceed probing + return ValueOrProceed.FromValue(null, false); + } + + var pluginDependency = this.pluginDependencyContext.PluginDependencies.FirstOrDefault(d => d.DependencyNameWithoutExtension == assemblyName.Name); + if (pluginDependency != null) + { + var dependency = this.pluginDependencyResolver.ResolvePluginDependencyToPath(initialPluginLoadDirectory, pluginDependency, this.pluginDependencyContext.AdditionalProbingPaths); + if (dependency != null) + return ValueOrProceed.FromValue(AssemblyFromStrategy.Releasable(LoadFromStream(dependency)), false); + } + + var localFile = Path.Combine(initialPluginLoadDirectory, assemblyName.Name + ".dll"); + if (this.fileSystemUtilities.DoesFileExist(localFile)) + { + return ValueOrProceed.FromValue(AssemblyFromStrategy.Releasable(LoadFromAssemblyPath(localFile)), false); + } + + return ValueOrProceed.Proceed(); + } + + protected virtual ValueOrProceed LoadFromRemote(string initialPluginLoadDirectory, AssemblyName assemblyName) + { + var assemblyFileName = $"{assemblyName.Name}.dll"; + if (this.fileSystemUtilities.DoesFileExist(Path.Combine(initialPluginLoadDirectory, assemblyFileName))) + { + return LoadDependencyFromLocalDisk(initialPluginLoadDirectory, assemblyFileName); + } + return ValueOrProceed.Proceed(); + } + + protected virtual ValueOrProceed LoadFromDefaultContext(string initialPluginLoadDirectory, AssemblyName assemblyName) + { + try + { + var assemblyShim = this.runtimeDefaultAssemblyLoadContext.LoadFromDefaultContext(assemblyName); + if (assemblyShim != null) + return ValueOrProceed.FromValue(assemblyShim, false); + } + catch (FileNotFoundException) { } // This can happen if the plugin uses a newer version of a package referenced in the host + + var hostAssembly = this.pluginDependencyContext.HostDependencies.FirstOrDefault(h => h.DependencyName.Name == assemblyName.Name); + if (hostAssembly != null && !hostAssembly.AllowDowngrade) + { + if (!hostAssembly.AllowDowngrade) + throw new AssemblyLoadingException($"Plugin Assembly reference {assemblyName.Name} with version {assemblyName.Version} was requested but not found in the host. The version from the host is {hostAssembly.DependencyName.Version}. Possible version mismatch. Please downgrade your plugin or add {assemblyName.Name} to downgradableHostAssemblies."); + } + + return ValueOrProceed.Proceed(); + } + + protected virtual ValueOrProceed LoadDependencyFromLocalDisk(string directory, string assemblyFileName) + { + var dependency = this.fileSystemUtilities.ReadDependencyFileFromDisk(directory, assemblyFileName); + + if (dependency == null) + return ValueOrProceed.Proceed(); + + return ValueOrProceed.FromValue(AssemblyFromStrategy.Releasable(Assembly.Load(this.fileSystemUtilities.ToByteArray(dependency))), false); + } + + protected override IntPtr LoadUnmanagedDll(string unmanagedDllName) + { + // This fixes the issue where the ALC is still alive and utilized in the host + if (this.disposed || this.disposing) + return IntPtr.Zero; + + IntPtr library = IntPtr.Zero; + + var nativeAssembly = assemblyLoadStrategy.LoadUnmanagedDll( + this.initialPluginLoadDirectory, + unmanagedDllName, + this.pluginDependencyContext, + LoadUnmanagedFromDependencyContext, + LoadUnmanagedFromRemote, + LoadUnmanagedFromDefault + ); + + if (!String.IsNullOrEmpty(nativeAssembly.Path)) + // Load via assembly path + library = LoadUnmanagedDllFromDependencyLookup(Path.GetFullPath(nativeAssembly.Path)); + else + // Load via provided pointer + library = nativeAssembly.Pointer; + + if (library != IntPtr.Zero && // If the library was found + !String.IsNullOrEmpty(nativeAssembly.Path) && // and it was found via the dependency lookup + !this.loadedNativeLibraries.ContainsKey(nativeAssembly.Path)) // and it was not already loaded + this.loadedNativeLibraries[nativeAssembly.Path] = library; // Add it to the list in order to have it unloaded later + + return library; + } + + /// + /// This override includes the netcore 3.0 resolver + /// + /// + /// + protected ValueOrProceed LoadUnmanagedFromDependencyContext(string initialPluginLoadDirectory, string unmanagedDllName) + { + string libraryPath = this.resolver.ResolveUnmanagedDllToPath(unmanagedDllName); + if (!String.IsNullOrEmpty(libraryPath)) + { + string runtimeCandidate = null; + if (this.nativeDependencyLoadPreference == NativeDependencyLoadPreference.PreferInstalledRuntime) + // Prefer loading from runtime folder + runtimeCandidate = this.pluginDependencyResolver.ResolvePlatformDependencyPathToRuntime(this.pluginPlatformVersion, libraryPath); + + return ValueOrProceed.FromValue(runtimeCandidate ?? libraryPath, false); + } + + var unmanagedDllNameWithoutFileExtension = Path.GetFileNameWithoutExtension(unmanagedDllName); + var platformDependency = this.pluginDependencyContext.PlatformDependencies.FirstOrDefault(d => d.DependencyNameWithoutExtension == unmanagedDllNameWithoutFileExtension); + if (platformDependency != null) + { + var pathToDependency = this.pluginDependencyResolver.ResolvePlatformDependencyToPath(initialPluginLoadDirectory, platformDependency, this.pluginDependencyContext.AdditionalProbingPaths); + if (!String.IsNullOrEmpty(pathToDependency)) + { + string runtimeCandidate = null; + if (this.nativeDependencyLoadPreference == NativeDependencyLoadPreference.PreferInstalledRuntime) + // Prefer loading from runtime folder + runtimeCandidate = this.pluginDependencyResolver.ResolvePlatformDependencyPathToRuntime(this.pluginPlatformVersion, pathToDependency); + + return ValueOrProceed.FromValue(runtimeCandidate ?? pathToDependency, false); + } + } + + return ValueOrProceed.FromValue(String.Empty, true); + } + + protected virtual ValueOrProceed LoadUnmanagedFromRemote(string initialPluginLoadDirectory, string unmanagedDllName) + { + var assemblyFileName = $"{unmanagedDllName}.dll"; + var pathToDependency = Path.Combine(initialPluginLoadDirectory, assemblyFileName); + if (this.fileSystemUtilities.DoesFileExist(pathToDependency)) + { + return ValueOrProceed.FromValue(pathToDependency, false); + } + return ValueOrProceed.FromValue(String.Empty, true); + } + + protected virtual ValueOrProceed LoadUnmanagedFromDefault(string initialPluginLoadDirectory, string unmanagedDllName) + { + var resolution = base.LoadUnmanagedDll(unmanagedDllName); + if (resolution == default(IntPtr)) + return ValueOrProceed.Proceed(); + + return ValueOrProceed.FromValue(resolution, false); + } + + /// + /// Load the assembly using the base.LoadUnmanagedDllFromPath functionality + /// + /// + /// A loaded native library pointer + protected virtual IntPtr LoadUnmanagedDllFromDependencyLookup(string fullPathToUnmanagedDll) => base.LoadUnmanagedDllFromPath(fullPathToUnmanagedDll); + + public async Task Unload() + { +#if SUPPORTS_UNLOADING + if (this.isCollectible) + base.Unload(); +#endif + } + + protected Assembly LoadAndAddToWeakReferences(AssemblyFromStrategy assemblyFromStrategy) + { + if (assemblyFromStrategy != null && assemblyFromStrategy.CanBeReleased) + this.assemblyReferences.Add(new System.WeakReference(assemblyFromStrategy.Assembly)); + + return assemblyFromStrategy?.Assembly; + } + + protected Assembly LoadAndAddToWeakReferences(Stream stream) + { + var assembly = base.LoadFromStream(stream); // ==> AssemblyLoadContext.LoadFromStream(Stream stream) + this.assemblyReferences.Add(new System.WeakReference(assembly)); + return assembly; + } + + + protected virtual void Dispose(bool disposing) + { + if (!this.disposed && disposing) + { + this.disposing = true; + + GC.Collect(); + GC.WaitForPendingFinalizers(); + + if (this.assemblyReferences != null) + foreach (var reference in this.assemblyReferences) + // https://docs.microsoft.com/en-us/dotnet/standard/assembly/unloadability#use-collectible-assemblyloadcontext + for (int i = 0; reference.IsAlive && (i < 10); i++) + { + GC.Collect(); + GC.WaitForPendingFinalizers(); + } + + + // Unload any loaded native assemblies + foreach (var nativeAssembly in this.loadedNativeLibraries) + this.nativeAssemblyUnloader.UnloadNativeAssembly(nativeAssembly.Key, nativeAssembly.Value); + + this.loadedPlugins.Clear(); + this.assemblyReferences.Clear(); + this.loadedNativeLibraries.Clear(); + this.pluginDependencyContext?.Dispose(); + this.pluginDependencyResolver?.Dispose(); + this.resolver?.Dispose(); + this.resolver = null; + this.loadedNativeLibraries = null; + this.loadedPlugins = null; + this.assemblyReferences = null; + this.assemblyLoadStrategy = null; + this.pluginDependencyContext = null; + this.pluginDependencyResolver = null; + this.fullPathToPluginAssembly = null; + this.initialPluginLoadDirectory = null; + this.pluginPlatformVersion = null; + this.nativeAssemblyUnloader = null; + this.pluginDependencyResolverFactory = null; + this.assemblyLoadStrategyFactory = null; + this.assemblyDependencyResolverFactory = null; + this.fileSystemUtilities = null; + this.runtimeDefaultAssemblyLoadContext = null; + this.pluginDependencyContextProvider = null; + } + this.disposed = true; + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + } +} \ No newline at end of file diff --git a/Vendor/Prise/AssemblyLoading/DefaultAssemblyLoadStrategy.cs b/Vendor/Prise/AssemblyLoading/DefaultAssemblyLoadStrategy.cs new file mode 100644 index 0000000..8bad9ce --- /dev/null +++ b/Vendor/Prise/AssemblyLoading/DefaultAssemblyLoadStrategy.cs @@ -0,0 +1,84 @@ +using System; +using System.Diagnostics; +using System.Linq; +using System.Reflection; + +namespace Prise.AssemblyLoading +{ + public class DefaultAssemblyLoadStrategy : IAssemblyLoadStrategy + { + public virtual AssemblyFromStrategy LoadAssembly( + string initialPluginLoadDirectory, + AssemblyName assemblyName, + IPluginDependencyContext pluginDependencyContext, + Func> loadFromDependencyContext, + Func> loadFromRemote, + Func> loadFromAppDomain) + { + if (assemblyName.Name == null) return null; + Debug.WriteLine($"{initialPluginLoadDirectory} Loading {assemblyName.Name} {assemblyName.Version}"); + ValueOrProceed valueOrProceed = ValueOrProceed.FromValue(null, true); + + var isHostAssembly = IsHostAssembly(assemblyName, pluginDependencyContext); + var isRemoteAssembly = IsRemoteAssembly(assemblyName, pluginDependencyContext); + + if (isHostAssembly && !isRemoteAssembly) // Load from Default App Domain (host) + { + Debug.WriteLine($"{initialPluginLoadDirectory} Loading {assemblyName.Name} {assemblyName.Version} from appDomain"); + var assemblyShim = loadFromAppDomain(initialPluginLoadDirectory, assemblyName); + if (assemblyShim.Value != null) + switch (assemblyShim.Value.RuntimeLoadFlag) + { + case RuntimeLoadFlag.FromRequestedVersion: + return null; // fallback to default loading mechanism + case RuntimeLoadFlag.FromRuntimeVersion: + return AssemblyFromStrategy.NotReleasable(assemblyShim.Value.Assembly); + } + } + + if (valueOrProceed.CanProceed) + valueOrProceed = loadFromDependencyContext(initialPluginLoadDirectory, assemblyName); + Debug.WriteLineIf(!valueOrProceed.CanProceed, $"{initialPluginLoadDirectory} Loaded {assemblyName.Name} {assemblyName.Version} from dependency context"); + + if (valueOrProceed.CanProceed) + { + valueOrProceed = loadFromRemote(initialPluginLoadDirectory, assemblyName); + Debug.WriteLineIf(!valueOrProceed.CanProceed, $"{initialPluginLoadDirectory} Loaded {assemblyName.Name} {assemblyName.Version} from remote"); + } + + return valueOrProceed.Value; + } + + public virtual NativeAssembly LoadUnmanagedDll( + string initialPluginLoadDirectory, + string unmanagedDllName, + IPluginDependencyContext pluginDependencyContext, + Func> loadFromDependencyContext, + Func> loadFromRemote, + Func> loadFromAppDomain) + { + ValueOrProceed valueOrProceed = ValueOrProceed.FromValue(String.Empty, true); + ValueOrProceed ptrValueOrProceed = ValueOrProceed.FromValue(IntPtr.Zero, true); + + valueOrProceed = loadFromDependencyContext(initialPluginLoadDirectory, unmanagedDllName); + + if (valueOrProceed.CanProceed) + ptrValueOrProceed = loadFromAppDomain(initialPluginLoadDirectory, unmanagedDllName); + + if (valueOrProceed.CanProceed && ptrValueOrProceed.CanProceed) + valueOrProceed = loadFromRemote(initialPluginLoadDirectory, unmanagedDllName); + + return NativeAssembly.Create(valueOrProceed.Value, ptrValueOrProceed.Value); + } + + protected virtual bool IsHostAssembly(AssemblyName assemblyName, IPluginDependencyContext pluginDependencyContext) => + pluginDependencyContext.HostDependencies.Any(h => + h.DependencyName.Name == assemblyName.Name + ); + + protected virtual bool IsRemoteAssembly(AssemblyName assemblyName, IPluginDependencyContext pluginDependencyContext) => + pluginDependencyContext.RemoteDependencies.Any(r => + r.DependencyName.Name == assemblyName.Name + ); + } +} \ No newline at end of file diff --git a/Vendor/Prise/AssemblyLoading/DefaultAssemblyLoader.cs b/Vendor/Prise/AssemblyLoading/DefaultAssemblyLoader.cs new file mode 100644 index 0000000..aea3995 --- /dev/null +++ b/Vendor/Prise/AssemblyLoading/DefaultAssemblyLoader.cs @@ -0,0 +1,126 @@ +using System; +using System.Collections.Concurrent; +using System.IO; +using System.Linq; +using System.Threading.Tasks; + +using Prise.Utils; + +namespace Prise.AssemblyLoading +{ + public class DefaultAssemblyLoader : IAssemblyLoader, IDisposable + { + private readonly Func assemblyLoadContextFactory; + protected ConcurrentDictionary loadContexts; + protected ConcurrentDictionary loadContextReferences; + + public DefaultAssemblyLoader(Func assemblyLoadContextFactory) + { + this.assemblyLoadContextFactory = assemblyLoadContextFactory.ThrowIfNull(nameof(assemblyLoadContextFactory)); + this.loadContexts = new ConcurrentDictionary(); + this.loadContextReferences = new ConcurrentDictionary(); + } + + public virtual Task Load(IPluginLoadContext pluginLoadContext) + { + if (pluginLoadContext == null) + throw new ArgumentNullException(nameof(pluginLoadContext)); + + var fullPathToAssembly = pluginLoadContext.FullPathToPluginAssembly.ThrowIfNullOrEmpty(nameof(pluginLoadContext.FullPathToPluginAssembly)); + + if (!Path.IsPathRooted(fullPathToAssembly)) + throw new AssemblyLoadingException($"FullPathToPluginAssembly {pluginLoadContext.FullPathToPluginAssembly} is not rooted, this must be a absolute path!"); + + var loadContext = this.assemblyLoadContextFactory(); + this.loadContexts[fullPathToAssembly] = loadContext; + this.loadContextReferences[fullPathToAssembly] = new System.WeakReference(loadContext); + return loadContext.LoadPluginAssembly(pluginLoadContext); + } + + public virtual Task Unload(IPluginLoadContext pluginLoadContext) + { + if (pluginLoadContext == null) + throw new ArgumentNullException(nameof(pluginLoadContext)); + + var fullPathToAssembly = pluginLoadContext.FullPathToPluginAssembly.ThrowIfNullOrEmpty(nameof(pluginLoadContext.FullPathToPluginAssembly)); + + if (!Path.IsPathRooted(fullPathToAssembly)) + throw new AssemblyLoadingException($"FullPathToPluginAssembly {pluginLoadContext.FullPathToPluginAssembly} is not rooted, this must be a absolute path!"); + + UnloadContexts(fullPathToAssembly); + + return Task.CompletedTask; + } + + protected virtual void UnloadContexts(string fullPathToAssembly) + { + UnloadAndCleanup(); + + GC.Collect(); + GC.WaitForPendingFinalizers(); + } + + protected virtual void UnloadAndCleanup(string fullPathToAssembly = null) + { + if (this.loadContexts != null) + { + var loadContexts = String.IsNullOrEmpty(fullPathToAssembly) ? + this.loadContexts.Where(c => c.Key == fullPathToAssembly).Select(c => c.Key) : + this.loadContexts.Select(c => c.Key); + foreach (var key in loadContexts) + { + this.loadContexts[key].Unload(); + this.loadContexts.TryRemove(key, out _); + } + } + + if (this.loadContextReferences != null) + { + var loadContextReferences = String.IsNullOrEmpty(fullPathToAssembly) ? + this.loadContextReferences.Where(c => c.Key == fullPathToAssembly).Select(c => c.Key) : + this.loadContextReferences.Select(c => c).Select(c => c.Key); + foreach (var key in loadContextReferences) + { + var reference = this.loadContextReferences[key]; + for (int i = 0; reference.IsAlive && (i < 10); i++) + { + GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced); + GC.WaitForPendingFinalizers(); + } + } + } + } + + protected virtual void DisposeAndUnloadContexts() + { + // Clean up all + this.UnloadAndCleanup(); + + this.loadContexts?.Clear(); + this.loadContexts = null; + + this.loadContextReferences?.Clear(); + this.loadContextReferences = null; + + GC.Collect(); // collects all unused memory + GC.WaitForPendingFinalizers(); // wait until GC has finished its work + GC.Collect(); + } + + protected bool disposed = false; + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + protected virtual void Dispose(bool disposing) + { + if (!this.disposed && disposing) + { + DisposeAndUnloadContexts(); + } + this.disposed = true; + } + } +} \ No newline at end of file diff --git a/Vendor/Prise/AssemblyLoading/DefaultNativeAssemblyUnloader.cs b/Vendor/Prise/AssemblyLoading/DefaultNativeAssemblyUnloader.cs new file mode 100644 index 0000000..21dcfa3 --- /dev/null +++ b/Vendor/Prise/AssemblyLoading/DefaultNativeAssemblyUnloader.cs @@ -0,0 +1,25 @@ +using System; +using System.Runtime.InteropServices; + +namespace Prise.AssemblyLoading +{ +#if !SUPPORTS_NATIVE_UNLOADING + internal static class NativeAssemblyUnloader + { + [DllImport("kernel32", SetLastError = true)] + internal static extern bool FreeLibrary(IntPtr hModule); + } +#endif + + public class DefaultNativeAssemblyUnloader : INativeAssemblyUnloader + { + public void UnloadNativeAssembly(string fullPathToLoadedNativeAssembly, IntPtr pointerToAssembly) + { +#if !SUPPORTS_NATIVE_UNLOADING + NativeAssemblyUnloader.FreeLibrary(pointerToAssembly); +#else + NativeLibrary.Free(pointerToAssembly); +#endif + } + } +} \ No newline at end of file diff --git a/Vendor/Prise/AssemblyLoading/DefaultPluginDependencyContext.cs b/Vendor/Prise/AssemblyLoading/DefaultPluginDependencyContext.cs new file mode 100644 index 0000000..2eb2aed --- /dev/null +++ b/Vendor/Prise/AssemblyLoading/DefaultPluginDependencyContext.cs @@ -0,0 +1,415 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Runtime.InteropServices; +using System.Runtime.Loader; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading.Tasks; +using Microsoft.Extensions.DependencyModel; +using NuGet.Versioning; +using Prise.Platform; +using Prise.Utils; + +namespace Prise.AssemblyLoading +{ + public interface IPluginDependencyContextProvider + { + Task FromPluginLoadContext(IPluginLoadContext pluginLoadContext); + } + + public class DefaultPluginDependencyContextProvider : IPluginDependencyContextProvider + { + private readonly IPlatformAbstraction platformAbstraction; + private readonly IRuntimePlatformContext runtimePlatformContext; + public DefaultPluginDependencyContextProvider(Func platformAbstractionFactory, Func runtimePlatformContextFactory) + { + this.platformAbstraction = platformAbstractionFactory.ThrowIfNull(nameof(platformAbstractionFactory))(); + this.runtimePlatformContext = runtimePlatformContextFactory.ThrowIfNull(nameof(runtimePlatformContextFactory))(); + } + + public Task FromPluginLoadContext(IPluginLoadContext pluginLoadContext) + { + var hostDependencies = new List(); + var remoteDependencies = new List(); + // var runtimePlatformContext = pluginLoadContext.RuntimePlatformContext.ThrowIfNull(nameof(pluginLoadContext.RuntimePlatformContext)); + + foreach (var type in pluginLoadContext.HostTypes) + // Load host types from current app domain + LoadAssemblyAndReferencesFromCurrentAppDomain(type.Assembly.GetName(), hostDependencies, pluginLoadContext.DowngradableHostTypes, pluginLoadContext.DowngradableHostAssemblies); + + foreach (var assemblyFileName in pluginLoadContext.HostAssemblies) + // Load host types from current app domain + LoadAssemblyAndReferencesFromCurrentAppDomain(assemblyFileName, hostDependencies, pluginLoadContext.DowngradableHostTypes, pluginLoadContext.DowngradableHostAssemblies); + + foreach (var type in pluginLoadContext.RemoteTypes) + remoteDependencies.Add(new RemoteDependency + { + DependencyName = type.Assembly.GetName() + }); + + var dependencyContext = GetDependencyContext(pluginLoadContext.FullPathToPluginAssembly); + var pluginFramework = dependencyContext.Target.Framework; + CheckFrameworkCompatibility(pluginLoadContext.HostFramework, pluginFramework, pluginLoadContext.IgnorePlatformInconsistencies); + + var pluginDependencies = GetPluginDependencies(dependencyContext); + var resourceDependencies = GetResourceDependencies(dependencyContext); + var platformDependencies = GetPlatformDependencies(dependencyContext, this.runtimePlatformContext.GetPlatformExtensions()); + + var pluginDependencyContext = new DefaultPluginDependencyContext( + pluginLoadContext.FullPathToPluginAssembly, + hostDependencies, + remoteDependencies, + pluginDependencies, + resourceDependencies, + platformDependencies, + pluginLoadContext.AdditionalProbingPaths + ); + + Validate(pluginDependencyContext); + + return Task.FromResult(pluginDependencyContext); + } + + private static void Validate(DefaultPluginDependencyContext dependencyContext) + { + var hostDependenciesThatExistInPlugin = dependencyContext.HostDependencies + .Join(dependencyContext.PluginDependencies, h => h.DependencyName.Name, p => p.DependencyNameWithoutExtension, (h, p) => new + { + Host = h, + Plugin = p + }); + + foreach (var duplicateDependency in hostDependenciesThatExistInPlugin) + { + Debug.WriteLine($"Plugin dependency {duplicateDependency.Plugin.DependencyNameWithoutExtension} {duplicateDependency.Plugin.SemVer} exists in the host"); + if (duplicateDependency.Host.SemVer > duplicateDependency.Plugin.SemVer) + Debug.WriteLine($"Host dependency {duplicateDependency.Host.DependencyName.Name} version {duplicateDependency.Host.SemVer} is newer than the Plugin {duplicateDependency.Plugin.SemVer}"); + if (duplicateDependency.Host.SemVer < duplicateDependency.Plugin.SemVer) + Debug.WriteLine($"Plugin dependency {duplicateDependency.Plugin.DependencyNameWithoutExtension} version {duplicateDependency.Plugin.SemVer} is newer than the Host {duplicateDependency.Host.SemVer}"); + } + } + + private static void CheckFrameworkCompatibility(string hostFramework, string pluginFramework, bool ignorePlatformInconsistencies) + { + if (ignorePlatformInconsistencies) + return; + + if (pluginFramework != hostFramework) + { + Debug.WriteLine($"Plugin framework {pluginFramework} does not match host framework {hostFramework}"); + + var pluginFrameworkType = pluginFramework.Split(new String[] { ",Version=v" }, StringSplitOptions.RemoveEmptyEntries)[0]; + var hostFrameworkType = hostFramework.Split(new String[] { ",Version=v" }, StringSplitOptions.RemoveEmptyEntries)[0]; + if (pluginFrameworkType.ToLower() == ".netstandard") + throw new AssemblyLoadingException($"Plugin framework {pluginFramework} might have compatibility issues with the host {hostFramework}, use the IgnorePlatformInconsistencies flag to skip this check."); + + if (pluginFrameworkType != hostFrameworkType) + throw new AssemblyLoadingException($"Plugin framework {pluginFramework} does not match the host {hostFramework}. Please target {hostFramework} in order to load the plugin."); + + var pluginFrameworkVersion = pluginFramework.Split(new String[] { ",Version=v" }, StringSplitOptions.RemoveEmptyEntries)[1]; + var hostFrameworkVersion = hostFramework.Split(new String[] { ",Version=v" }, StringSplitOptions.RemoveEmptyEntries)[1]; + var pluginFrameworkVersionMajor = int.Parse(pluginFrameworkVersion.Split(new String[] { "." }, StringSplitOptions.RemoveEmptyEntries)[0]); + var pluginFrameworkVersionMinor = int.Parse(pluginFrameworkVersion.Split(new String[] { "." }, StringSplitOptions.RemoveEmptyEntries)[1]); + var hostFrameworkVersionMajor = int.Parse(hostFrameworkVersion.Split(new String[] { "." }, StringSplitOptions.RemoveEmptyEntries)[0]); + var hostFrameworkVersionMinor = int.Parse(hostFrameworkVersion.Split(new String[] { "." }, StringSplitOptions.RemoveEmptyEntries)[1]); + + if (pluginFrameworkVersionMajor > hostFrameworkVersionMajor || // If the major version of the plugin is higher + (pluginFrameworkVersionMajor == hostFrameworkVersionMajor && pluginFrameworkVersionMinor > hostFrameworkVersionMinor)) // Or the major version is the same but the minor version is higher + throw new AssemblyLoadingException($"Plugin framework version {pluginFramework} is newer than the Host {hostFramework}. Please upgrade the Host to load this Plugin."); + } + } + + private static void LoadAssemblyAndReferencesFromCurrentAppDomain(AssemblyName assemblyName, List hostDependencies, IEnumerable downgradableHostTypes, IEnumerable downgradableAssemblies) + { + if (assemblyName?.Name == null || hostDependencies.Any(h => h.DependencyName.Name == assemblyName.Name)) + return; // Break condition + + hostDependencies.Add(new HostDependency + { + DependencyName = assemblyName, + AllowDowngrade = + downgradableHostTypes.Any(t => t.Assembly.GetName().Name == assemblyName.Name) || + downgradableAssemblies.Any(a => a == assemblyName.Name) + }); + + try + { + var assembly = AssemblyLoadContext.Default.LoadFromAssemblyName(assemblyName); + foreach (var reference in assembly.GetReferencedAssemblies()) + LoadAssemblyAndReferencesFromCurrentAppDomain(reference, hostDependencies, downgradableHostTypes, downgradableAssemblies); + } + catch (FileNotFoundException) + { + // This happens when the assembly is a platform assembly, log it + // logger.LoadReferenceFromAppDomainFailed(assemblyName); + } + } + + private static void LoadAssemblyAndReferencesFromCurrentAppDomain(string assemblyFileName, List hostDependencies, IEnumerable downgradableHostTypes, IEnumerable downgradableAssemblies) + { + var assemblyName = new AssemblyName(assemblyFileName); + if (assemblyFileName == null || hostDependencies.Any(h => h.DependencyName.Name == assemblyName.Name)) + return; // Break condition + + hostDependencies.Add(new HostDependency + { + DependencyName = assemblyName, + AllowDowngrade = + downgradableHostTypes.Any(t => t.Assembly.GetName().Name == assemblyName.Name) || + downgradableAssemblies.Any(a => a == assemblyName.Name) + }); + + try + { + var assembly = AssemblyLoadContext.Default.LoadFromAssemblyName(assemblyName); + foreach (var reference in assembly.GetReferencedAssemblies()) + LoadAssemblyAndReferencesFromCurrentAppDomain(reference, hostDependencies, downgradableHostTypes, downgradableAssemblies); + } + catch (FileNotFoundException) + { + // This happens when the assembly is a platform assembly, log it + // logger.LoadReferenceFromAppDomainFailed(assemblyName); + } + } + +#if SUPPORTS_NATIVE_PLATFORM_ABSTRACTIONS + private string GetCorrectRuntimeIdentifier() + { + + var runtimeIdentifier = RuntimeInformation.RuntimeIdentifier; + + if (this.platformAbstraction.IsOSX() || this.platformAbstraction.IsWindows()) + return runtimeIdentifier; + + // Other: Linux, FreeBSD, ... + return $"linux-{RuntimeInformation.ProcessArchitecture.ToString().ToLower()}"; + } +#else + private string GetCorrectRuntimeIdentifier() + { + + var runtimeIdentifier = RuntimeInformation.RuntimeIdentifier; + if (this.platformAbstraction.IsOSX() || this.platformAbstraction.IsWindows()) + return runtimeIdentifier; + + return $"{RuntimeInformation.OSDescription.ToString().ToLower()}-{RuntimeInformation.ProcessArchitecture}"; + } +#endif + + private IEnumerable GetPluginDependencies(DependencyContext pluginDependencyContext) + { + var dependencies = new List(); + var runtimeId = GetCorrectRuntimeIdentifier(); + var dependencyGraph = DependencyContext.Default.RuntimeGraph.FirstOrDefault(g => g.Runtime == runtimeId); + // List of supported runtimes, includes the default runtime and the fallbacks for this dependency context + var runtimes = new List { dependencyGraph?.Runtime }.AddRangeToList(dependencyGraph?.Fallbacks); + foreach (var runtimeLibrary in pluginDependencyContext.RuntimeLibraries) + { + var assets = runtimeLibrary.RuntimeAssemblyGroups.GetDefaultAssets(); + + foreach (var runtime in runtimes) + { + var runtimeSpecificGroup = runtimeLibrary.RuntimeAssemblyGroups.FirstOrDefault(g => g.Runtime == runtime); + if (runtimeSpecificGroup != null) + { + assets = runtimeSpecificGroup.AssetPaths; + break; + } + } + foreach (var asset in assets) + { + var path = asset.StartsWith("lib/") + ? Path.GetFileName(asset) + : asset; + + dependencies.Add(new PluginDependency + { + DependencyNameWithoutExtension = Path.GetFileNameWithoutExtension(asset), + SemVer = ParseSemVer(runtimeLibrary.Version), + DependencyPath = path, + ProbingPath = Path.Combine(runtimeLibrary.Name.ToLowerInvariant(), runtimeLibrary.Version, path) + }); + } + } + return dependencies; + } + + private SemanticVersion ParseSemVer(string version) + { + if (SemanticVersion.TryParse(version, out var semVer)) + return semVer; + + var versions = version.Split('.'); + if (versions.Length > 3) + return new SemanticVersion(int.Parse(versions[0]), int.Parse(versions[1]), int.Parse(versions[2]), versions[3]); + + return new SemanticVersion(int.Parse(versions[0]), int.Parse(versions[1]), int.Parse(versions[2])); + } + + private static IEnumerable GetPluginReferenceDependencies(DependencyContext pluginDependencyContext) + { + var dependencies = new List(); + foreach (var referenceAssembly in pluginDependencyContext.CompileLibraries.Where(r => r.Type == "referenceassembly")) + { + foreach (var assembly in referenceAssembly.Assemblies) + { + dependencies.Add(new PluginDependency + { + DependencyNameWithoutExtension = Path.GetFileNameWithoutExtension(assembly), + SemVer = SemanticVersion.Parse(referenceAssembly.Version), + DependencyPath = Path.Join("refs", assembly) + }); + } + } + return dependencies; + } + + private IEnumerable GetPlatformDependencies(DependencyContext pluginDependencyContext, IEnumerable platformExtensions) + { + var dependencies = new List(); + var runtimeId = GetCorrectRuntimeIdentifier(); + var dependencyGraph = DependencyContext.Default.RuntimeGraph.FirstOrDefault(g => g.Runtime == runtimeId); + // List of supported runtimes, includes the default runtime and the fallbacks for this dependency context + var runtimes = new List { dependencyGraph?.Runtime }.AddRangeToList(dependencyGraph?.Fallbacks); + foreach (var runtimeLibrary in pluginDependencyContext.RuntimeLibraries) + { + var assets = runtimeLibrary.NativeLibraryGroups.GetDefaultAssets(); + + foreach (var runtime in runtimes) + { + var runtimeSpecificGroup = runtimeLibrary.NativeLibraryGroups.FirstOrDefault(g => g.Runtime == runtime); + if (runtimeSpecificGroup != null) + { + assets = runtimeSpecificGroup.AssetPaths; + break; + } + } + foreach (var asset in assets.Where(a => platformExtensions.Contains(Path.GetExtension(a)))) // Only load assemblies and not debug files + { + SemanticVersion semVer; + if (!SemanticVersion.TryParse(runtimeLibrary.Version, out semVer)) + // Take first 3 digits + semVer = SemanticVersion.Parse(String.Join('.',runtimeLibrary.Version.Split(".").Take(3).ToArray())); + + dependencies.Add(new PlatformDependency + { + DependencyNameWithoutExtension = Path.GetFileNameWithoutExtension(asset), + SemVer = semVer, + DependencyPath = asset + }); + } + } + return dependencies; + } + + private static IEnumerable GetResourceDependencies(DependencyContext pluginDependencyContext) + { + var dependencies = new List(); + foreach (var runtimeLibrary in pluginDependencyContext.RuntimeLibraries + .Where(l => l.ResourceAssemblies != null && l.ResourceAssemblies.Any())) + { + dependencies.AddRange(runtimeLibrary.ResourceAssemblies + .Where(r => !String.IsNullOrEmpty(Path.GetDirectoryName(Path.GetDirectoryName(r.Path)))) + .Select(r => + new PluginResourceDependency + { + Path = Path.Combine(runtimeLibrary.Name.ToLowerInvariant(), + runtimeLibrary.Version, + r.Path) + })); + } + return dependencies; + } + + private static DependencyContext GetDependencyContext(string fullPathToPluginAssembly) + { + var file = File.OpenRead(Path.Combine(Path.GetDirectoryName(fullPathToPluginAssembly), $"{Path.GetFileNameWithoutExtension(fullPathToPluginAssembly)}.deps.json")); + return new DependencyContextJsonReader().Read(file); + } + } + + public class DefaultPluginDependencyContext : IPluginDependencyContext + { + public string FullPathToPluginAssembly { get; set; } + public IEnumerable HostDependencies { get; set; } + public IEnumerable RemoteDependencies { get; set; } + public IEnumerable PluginDependencies { get; set; } + public IEnumerable PluginResourceDependencies { get; set; } + public IEnumerable PlatformDependencies { get; set; } + public IEnumerable AdditionalProbingPaths { get; set; } + internal DefaultPluginDependencyContext(string fullPathToPluginAssembly, + IEnumerable hostDependencies, + IEnumerable remoteDependencies, + IEnumerable pluginDependencies, + IEnumerable pluginResourceDependencies, + IEnumerable platformDependencies, + IEnumerable additionalProbingPaths) + { + this.FullPathToPluginAssembly = fullPathToPluginAssembly.ThrowIfNull(nameof(fullPathToPluginAssembly)); + this.HostDependencies = hostDependencies.ThrowIfNull(nameof(hostDependencies)); + this.RemoteDependencies = remoteDependencies.ThrowIfNull(nameof(remoteDependencies)); + this.PluginDependencies = pluginDependencies.ThrowIfNull(nameof(pluginDependencies)); + this.PluginResourceDependencies = pluginResourceDependencies.ThrowIfNull(nameof(pluginResourceDependencies)); + this.PlatformDependencies = platformDependencies.ThrowIfNull(nameof(platformDependencies)); + this.AdditionalProbingPaths = additionalProbingPaths ?? Enumerable.Empty(); + } + + public override string ToString() + { + var builder = new StringBuilder(); + builder.AppendLine($"Dependency context for plugin: {this.FullPathToPluginAssembly}"); + + builder.AppendLine($"HostDependencies"); + foreach (var p in this.HostDependencies) + builder.AppendLine($"{p.DependencyName.Name} {p.DependencyName.Version}"); + + builder.AppendLine($""); + builder.AppendLine($"RemoteDependencies"); + foreach (var p in this.RemoteDependencies) + builder.AppendLine($"{p.DependencyName.Name} {p.DependencyName.Version}"); + + builder.AppendLine($""); + builder.AppendLine($"PlatformDependencies"); + foreach (var p in this.PlatformDependencies) + builder.AppendLine($"{p.DependencyPath} {p.DependencyNameWithoutExtension} {p.SemVer}"); + + builder.AppendLine($""); + builder.AppendLine($"PluginDependencies"); + foreach (var p in this.PluginDependencies) + builder.AppendLine($"{p.DependencyPath} {p.DependencyNameWithoutExtension} {p.SemVer}"); + + builder.AppendLine($""); + builder.AppendLine($"PluginResourceDependencies"); + foreach (var p in this.PluginResourceDependencies) + builder.AppendLine($"{p.Path}"); + + return builder.ToString(); + } + + private bool disposed = false; + protected virtual void Dispose(bool disposing) + { + if (!this.disposed && disposing) + { + this.FullPathToPluginAssembly = null; + this.HostDependencies = null; + this.RemoteDependencies = null; + this.PluginDependencies = null; + this.PluginResourceDependencies = null; + this.PlatformDependencies = null; + this.AdditionalProbingPaths = null; + } + this.disposed = true; + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + } +} \ No newline at end of file diff --git a/Vendor/Prise/AssemblyLoading/DefaultPluginDependencyResolver.cs b/Vendor/Prise/AssemblyLoading/DefaultPluginDependencyResolver.cs new file mode 100644 index 0000000..4d4a03d --- /dev/null +++ b/Vendor/Prise/AssemblyLoading/DefaultPluginDependencyResolver.cs @@ -0,0 +1,126 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; + +using Prise.Utils; + +namespace Prise.AssemblyLoading +{ + public class DefaultPluginDependencyResolver : IPluginDependencyResolver + { + protected IRuntimePlatformContext runtimePlatformContext; + + public DefaultPluginDependencyResolver(Func runtimePlatformContextFactory) + { + this.runtimePlatformContext = runtimePlatformContextFactory.ThrowIfNull(nameof(runtimePlatformContextFactory))(); + } + + public virtual Stream ResolvePluginDependencyToPath(string initialPluginLoadDirectory, PluginDependency dependency, IEnumerable additionalProbingPaths) + { + var localFile = Path.Combine(initialPluginLoadDirectory, dependency.DependencyPath); + if (File.Exists(localFile)) + { + return File.OpenRead(localFile); + } + + foreach (var probingPath in additionalProbingPaths) + { + var candidate = Path.Combine(probingPath, dependency.ProbingPath); + if (File.Exists(candidate)) + { + return File.OpenRead(candidate); + } + } + + foreach (var candidate in runtimePlatformContext.GetPluginDependencyNames(dependency.DependencyNameWithoutExtension)) + { + var candidateLocation = Path.Combine(initialPluginLoadDirectory, candidate); + if (File.Exists(candidateLocation)) + { + return File.OpenRead(candidateLocation); + } + } + return null; + } + + public virtual string ResolvePlatformDependencyToPath(string initialPluginLoadDirectory, PlatformDependency dependency, IEnumerable additionalProbingPaths) + { + foreach (var candidate in runtimePlatformContext.GetPlatformDependencyNames(dependency.DependencyNameWithoutExtension)) + { + var candidateLocation = Path.Combine(initialPluginLoadDirectory, candidate); + if (File.Exists(candidateLocation)) + { + return candidateLocation; + } + } + + var local = Path.Combine(initialPluginLoadDirectory, dependency.DependencyPath); + if (File.Exists(local)) + { + return local; + } + + foreach (var searchPath in additionalProbingPaths) + { + var candidate = Path.Combine(searchPath, dependency.ProbingPath); + if (File.Exists(candidate)) + { + return candidate; + } + } + + return null; + } + + public virtual string ResolvePlatformDependencyPathToRuntime(PluginPlatformVersion pluginPlatformVersion, string platformDependencyPath) + { + var platformDependencyFileVersion = FileVersionInfo.GetVersionInfo(platformDependencyPath); + var platformDependencyName = Path.GetFileName(platformDependencyPath); + var runtimeInformation = this.runtimePlatformContext.GetRuntimeInfo(); + + var runtimes = runtimeInformation.Runtimes; + if (pluginPlatformVersion.IsSpecified) + { + // First filter on specific version + runtimes = runtimes.Where(r => r.Version == pluginPlatformVersion.Version); + // Then, filter on target runtime, this is not always provided + if (pluginPlatformVersion.Runtime != RuntimeType.UnSpecified) + runtimes = runtimes.Where(r => r.RuntimeType == pluginPlatformVersion.Runtime); + + if (!runtimes.Any()) + throw new AssemblyLoadingException($"Requisted platform was not installed {pluginPlatformVersion.Runtime} {pluginPlatformVersion.Version}"); + } + + foreach (var runtime in runtimes.OrderByDescending(r => r.Version)) + { + var candidateFilePath = Directory.GetFiles(runtime.Location).FirstOrDefault(f => String.Compare(Path.GetFileName(f), platformDependencyName) == 0); + if (!String.IsNullOrEmpty(candidateFilePath)) + { + var candidateFileVersion = FileVersionInfo.GetVersionInfo(candidateFilePath); + if (String.Compare(platformDependencyFileVersion.FileVersion, candidateFileVersion.FileVersion) == 0) + return candidateFilePath; + } + } + + return null; + } + + protected bool disposed = false; + protected virtual void Dispose(bool disposing) + { + if (!this.disposed && disposing) + { + this.runtimePlatformContext = null; + } + this.disposed = true; + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + } +} \ No newline at end of file diff --git a/Vendor/Prise/AssemblyLoading/HostDependency.cs b/Vendor/Prise/AssemblyLoading/HostDependency.cs new file mode 100644 index 0000000..5757806 --- /dev/null +++ b/Vendor/Prise/AssemblyLoading/HostDependency.cs @@ -0,0 +1,12 @@ +using System.Reflection; +using NuGet.Versioning; + +namespace Prise.AssemblyLoading +{ + public class HostDependency + { + public AssemblyName DependencyName { get; set; } + public SemanticVersion SemVer => new SemanticVersion(DependencyName.Version.Major, DependencyName.Version.Minor, DependencyName.Version.Revision); + public bool AllowDowngrade { get; set; } + } +} \ No newline at end of file diff --git a/Vendor/Prise/AssemblyLoading/IAssemblyDependencyResolver.cs b/Vendor/Prise/AssemblyLoading/IAssemblyDependencyResolver.cs new file mode 100644 index 0000000..1acf64c --- /dev/null +++ b/Vendor/Prise/AssemblyLoading/IAssemblyDependencyResolver.cs @@ -0,0 +1,12 @@ +using System; +using System.Reflection; +using System.Runtime.Loader; + +namespace Prise.AssemblyLoading +{ + public interface IAssemblyDependencyResolver : IDisposable + { + string ResolveAssemblyToPath(AssemblyName assemblyName); + string ResolveUnmanagedDllToPath(string unmanagedDllName); + } +} \ No newline at end of file diff --git a/Vendor/Prise/AssemblyLoading/IAssemblyLoadContext.cs b/Vendor/Prise/AssemblyLoading/IAssemblyLoadContext.cs new file mode 100644 index 0000000..de325c6 --- /dev/null +++ b/Vendor/Prise/AssemblyLoading/IAssemblyLoadContext.cs @@ -0,0 +1,22 @@ +using System; +using System.Threading.Tasks; + + +namespace Prise.AssemblyLoading +{ + public interface IAssemblyLoadContext : IDisposable + { + /// + /// Loads a specific plugin assembly into the current IAssemblyLoader + /// + /// The loadcontext for the plugin + /// + Task LoadPluginAssembly(IPluginLoadContext loadContext); + + /// + /// Unloads all assemblies that were loaded for this plugin + /// + /// + Task Unload(); + } +} \ No newline at end of file diff --git a/Vendor/Prise/AssemblyLoading/IAssemblyLoadStrategy.cs b/Vendor/Prise/AssemblyLoading/IAssemblyLoadStrategy.cs new file mode 100644 index 0000000..4253115 --- /dev/null +++ b/Vendor/Prise/AssemblyLoading/IAssemblyLoadStrategy.cs @@ -0,0 +1,44 @@ +using System; +using System.Reflection; + +namespace Prise.AssemblyLoading +{ + public interface IAssemblyLoadStrategy + { + /// + /// Loads a dependency assembly for the current plugin + /// + /// Directory where the plugin was initially loaded from + /// + /// + /// + /// + /// + /// A loaded assembly + AssemblyFromStrategy LoadAssembly( + string initialPluginLoadDirectory, + AssemblyName assemblyName, + IPluginDependencyContext pluginDependencyContext, + Func> loadFromDependencyContext, + Func> loadFromRemote, + Func> loadFromAppDomain); + + /// + /// Loads a native assembly + /// + /// Directory where the plugin was initially loaded from + /// + /// + /// + /// + /// + /// The path to a native assembly + NativeAssembly LoadUnmanagedDll( + string initialPluginLoadDirectory, + string unmanagedDllName, + IPluginDependencyContext pluginDependencyContext, + Func> loadFromDependencyContext, + Func> loadFromRemote, + Func> loadFromAppDomain); + } +} \ No newline at end of file diff --git a/Vendor/Prise/AssemblyLoading/IAssemblyLoader.cs b/Vendor/Prise/AssemblyLoading/IAssemblyLoader.cs new file mode 100644 index 0000000..bb2681a --- /dev/null +++ b/Vendor/Prise/AssemblyLoading/IAssemblyLoader.cs @@ -0,0 +1,12 @@ +using System; +using System.Threading.Tasks; + + +namespace Prise.AssemblyLoading +{ + public interface IAssemblyLoader : IDisposable + { + Task Load(IPluginLoadContext pluginLoadContext); + Task Unload(IPluginLoadContext pluginLoadContext); + } +} \ No newline at end of file diff --git a/Vendor/Prise/AssemblyLoading/INativeAssemblyUnloader.cs b/Vendor/Prise/AssemblyLoading/INativeAssemblyUnloader.cs new file mode 100644 index 0000000..1501124 --- /dev/null +++ b/Vendor/Prise/AssemblyLoading/INativeAssemblyUnloader.cs @@ -0,0 +1,9 @@ +using System; + +namespace Prise.AssemblyLoading +{ + public interface INativeAssemblyUnloader + { + void UnloadNativeAssembly(string fullPathToLoadedNativeAssembly, IntPtr pointerToAssembly); + } +} \ No newline at end of file diff --git a/Vendor/Prise/AssemblyLoading/IPluginDependencyContext.cs b/Vendor/Prise/AssemblyLoading/IPluginDependencyContext.cs new file mode 100644 index 0000000..d30c66c --- /dev/null +++ b/Vendor/Prise/AssemblyLoading/IPluginDependencyContext.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; + +namespace Prise.AssemblyLoading +{ + public interface IPluginDependencyContext : IDisposable + { + string FullPathToPluginAssembly { get; } + /// + /// Host dependencies are detected automatically by reading out the deps.json file + /// + /// + IEnumerable HostDependencies { get; } + /// + /// Remote dependencies are specified manually via the AddRemoteType builder + /// + /// + IEnumerable RemoteDependencies { get; } + /// + /// Plugin dependencies are detected automatically by reading out the deps.json file + /// + /// + IEnumerable PluginDependencies { get; } + IEnumerable PluginResourceDependencies { get; } + IEnumerable PlatformDependencies { get; } + IEnumerable AdditionalProbingPaths { get; } + } +} \ No newline at end of file diff --git a/Vendor/Prise/AssemblyLoading/IPluginDependencyResolver.cs b/Vendor/Prise/AssemblyLoading/IPluginDependencyResolver.cs new file mode 100644 index 0000000..31f0ab1 --- /dev/null +++ b/Vendor/Prise/AssemblyLoading/IPluginDependencyResolver.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.IO; + + +namespace Prise.AssemblyLoading +{ + public interface IPluginDependencyResolver : IDisposable + { + Stream ResolvePluginDependencyToPath(string initialPluginLoadDirectory, PluginDependency dependency, IEnumerable additionalProbingPaths); + string ResolvePlatformDependencyToPath(string initialPluginLoadDirectory, PlatformDependency dependency, IEnumerable additionalProbingPaths); + string ResolvePlatformDependencyPathToRuntime(PluginPlatformVersion pluginPlatformVersion, string platformDependencyPath); + } +} \ No newline at end of file diff --git a/Vendor/Prise/AssemblyLoading/IRuntimeDefaultAssemblyContext.cs b/Vendor/Prise/AssemblyLoading/IRuntimeDefaultAssemblyContext.cs new file mode 100644 index 0000000..48e87aa --- /dev/null +++ b/Vendor/Prise/AssemblyLoading/IRuntimeDefaultAssemblyContext.cs @@ -0,0 +1,9 @@ +using System.Reflection; + +namespace Prise.AssemblyLoading +{ + public interface IRuntimeDefaultAssemblyContext + { + RuntimeAssemblyShim LoadFromDefaultContext(AssemblyName assemblyName); + } +} \ No newline at end of file diff --git a/Vendor/Prise/AssemblyLoading/InMemoryAssemblyLoadContext.cs b/Vendor/Prise/AssemblyLoading/InMemoryAssemblyLoadContext.cs new file mode 100644 index 0000000..41dfe3e --- /dev/null +++ b/Vendor/Prise/AssemblyLoading/InMemoryAssemblyLoadContext.cs @@ -0,0 +1,48 @@ +using System; +using System.IO; +using System.Reflection; +using System.Runtime.Loader; + +namespace Prise.AssemblyLoading +{ + /// + /// This base class will load all assemblies in memory by default and is Collectible by default + /// + public abstract class InMemoryAssemblyLoadContext : AssemblyLoadContext + { + protected bool disposed = false; + protected bool disposing = false; + protected bool isCollectible = false; + protected InMemoryAssemblyLoadContext() { } + + protected InMemoryAssemblyLoadContext(bool isCollectible) +#if SUPPORTS_UNLOADING + : base($"InMemoryAssemblyLoadContext{Guid.NewGuid().ToString("N")}", isCollectible: isCollectible) +#endif + { +#if SUPPORTS_UNLOADING + this.isCollectible = isCollectible; +#else + this.isCollectible = false; +#endif + } + + public new Assembly LoadFromAssemblyPath(string path) + { + // This fixes the issue where the ALC is still alive and utilized in the host + if (this.disposed || this.disposing) + return null; + + try + { + using (var stream = File.OpenRead(path)) + return LoadFromStream(stream); + } + catch (InvalidOperationException ex) + { + throw new AssemblyLoadingException($"Assembly at {path} could not be loaded (locked dll file)", ex); + } + } + } + +} \ No newline at end of file diff --git a/Vendor/Prise/AssemblyLoading/NativeAssembly.cs b/Vendor/Prise/AssemblyLoading/NativeAssembly.cs new file mode 100644 index 0000000..c05cda6 --- /dev/null +++ b/Vendor/Prise/AssemblyLoading/NativeAssembly.cs @@ -0,0 +1,15 @@ +using System; + +namespace Prise.AssemblyLoading +{ + /// + /// Represents a native library through either its full Path or a Pointer to an assembly in memory + /// + public class NativeAssembly + { + public string Path { get; private set; } + public IntPtr Pointer { get; private set; } + + public static NativeAssembly Create(string path, IntPtr pointer) => new NativeAssembly { Path = path, Pointer = pointer }; + } +} \ No newline at end of file diff --git a/Vendor/Prise/AssemblyLoading/PlatformDependency.cs b/Vendor/Prise/AssemblyLoading/PlatformDependency.cs new file mode 100644 index 0000000..2e1c80a --- /dev/null +++ b/Vendor/Prise/AssemblyLoading/PlatformDependency.cs @@ -0,0 +1,12 @@ +using NuGet.Versioning; + +namespace Prise.AssemblyLoading +{ + public class PlatformDependency + { + public string DependencyNameWithoutExtension { get; set; } + public SemanticVersion SemVer { get; set; } + public string DependencyPath { get; set; } + public string ProbingPath { get; set; } + } +} \ No newline at end of file diff --git a/Vendor/Prise/AssemblyLoading/PluginDependency.cs b/Vendor/Prise/AssemblyLoading/PluginDependency.cs new file mode 100644 index 0000000..d5d2479 --- /dev/null +++ b/Vendor/Prise/AssemblyLoading/PluginDependency.cs @@ -0,0 +1,13 @@ +using System; +using NuGet.Versioning; + +namespace Prise.AssemblyLoading +{ + public class PluginDependency + { + public string DependencyNameWithoutExtension { get; set; } + public SemanticVersion SemVer { get; set; } + public string DependencyPath { get; set; } + public string ProbingPath { get; set; } + } +} \ No newline at end of file diff --git a/Vendor/Prise/AssemblyLoading/PluginResourceDependency.cs b/Vendor/Prise/AssemblyLoading/PluginResourceDependency.cs new file mode 100644 index 0000000..8ece6b7 --- /dev/null +++ b/Vendor/Prise/AssemblyLoading/PluginResourceDependency.cs @@ -0,0 +1,7 @@ +namespace Prise.AssemblyLoading +{ + public class PluginResourceDependency + { + public string Path { get; set; } + } +} \ No newline at end of file diff --git a/Vendor/Prise/AssemblyLoading/RemoteDependency.cs b/Vendor/Prise/AssemblyLoading/RemoteDependency.cs new file mode 100644 index 0000000..9858378 --- /dev/null +++ b/Vendor/Prise/AssemblyLoading/RemoteDependency.cs @@ -0,0 +1,11 @@ +using System.Reflection; +using NuGet.Versioning; + +namespace Prise.AssemblyLoading +{ + public class RemoteDependency + { + public AssemblyName DependencyName { get; set; } + public SemanticVersion SemVer => new SemanticVersion(DependencyName.Version.Major, DependencyName.Version.Minor, DependencyName.Version.Revision); + } +} \ No newline at end of file diff --git a/Vendor/Prise/AssemblyLoading/RuntimeAssemblyShim.cs b/Vendor/Prise/AssemblyLoading/RuntimeAssemblyShim.cs new file mode 100644 index 0000000..912ccfa --- /dev/null +++ b/Vendor/Prise/AssemblyLoading/RuntimeAssemblyShim.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Reflection; + +namespace Prise.AssemblyLoading +{ + public class RuntimeAssemblyShim : IAssemblyShim + { + private readonly Assembly assembly; + private readonly RuntimeLoadFlag flag; + public RuntimeAssemblyShim(Assembly assembly, RuntimeLoadFlag flag) + { + this.assembly = assembly; + this.flag = flag; + } + + public Assembly Assembly => assembly; + public IEnumerable Types => assembly.GetTypes(); + public RuntimeLoadFlag RuntimeLoadFlag => flag; + } +} \ No newline at end of file diff --git a/Vendor/Prise/AssemblyLoading/RuntimeDefaultAssemblyContext.cs b/Vendor/Prise/AssemblyLoading/RuntimeDefaultAssemblyContext.cs new file mode 100644 index 0000000..a64eec3 --- /dev/null +++ b/Vendor/Prise/AssemblyLoading/RuntimeDefaultAssemblyContext.cs @@ -0,0 +1,33 @@ +using System.Reflection; +using System.Runtime.Loader; +using System.Linq; +using System; +using System.Collections.Generic; +using System.Diagnostics; + +namespace Prise.AssemblyLoading +{ + public class RuntimeDefaultAssemblyContext : IRuntimeDefaultAssemblyContext + { + public RuntimeAssemblyShim LoadFromDefaultContext(AssemblyName assemblyName) + { + var candidate = GetLoadedAssemblies().FirstOrDefault(a => a.GetName().Name == assemblyName.Name); + var candidateName = candidate != null ? candidate.GetName() : null; + + if (candidateName != null && candidateName.Version != assemblyName.Version) + { + Debug.WriteLine($"Requested version for {assemblyName.Name} {assemblyName.Version} is not loaded in the app domain, loading version {candidateName.Version}"); + // Inject the dependency context here and load the correct version + return new RuntimeAssemblyShim(AssemblyLoadContext.Default.LoadFromAssemblyName(candidateName), RuntimeLoadFlag.FromRuntimeVersion); + } + + return new RuntimeAssemblyShim(AssemblyLoadContext.Default.LoadFromAssemblyName(assemblyName), RuntimeLoadFlag.FromRequestedVersion); + } + +#if SUPPORTS_LOADED_ASSEMBLIES + protected IEnumerable GetLoadedAssemblies() => AssemblyLoadContext.Default.Assemblies; +#else + protected IEnumerable GetLoadedAssemblies() => AppDomain.CurrentDomain.GetAssemblies(); +#endif + } +} \ No newline at end of file diff --git a/Vendor/Prise/AssemblyLoading/RuntimeLoadFlag.cs b/Vendor/Prise/AssemblyLoading/RuntimeLoadFlag.cs new file mode 100644 index 0000000..f4eb7ba --- /dev/null +++ b/Vendor/Prise/AssemblyLoading/RuntimeLoadFlag.cs @@ -0,0 +1,8 @@ +namespace Prise.AssemblyLoading +{ + public enum RuntimeLoadFlag + { + FromRequestedVersion, + FromRuntimeVersion + } +} \ No newline at end of file diff --git a/Vendor/Prise/AssemblyLoading/ValueOrProceed.cs b/Vendor/Prise/AssemblyLoading/ValueOrProceed.cs new file mode 100644 index 0000000..77a367e --- /dev/null +++ b/Vendor/Prise/AssemblyLoading/ValueOrProceed.cs @@ -0,0 +1,19 @@ +namespace Prise.AssemblyLoading +{ + public class ValueOrProceed + { + public static ValueOrProceed Proceed() => new ValueOrProceed + { + CanProceed = true + }; + + public static ValueOrProceed FromValue(T value, bool proceed) => new ValueOrProceed + { + Value = value, + CanProceed = proceed + }; + + public T Value { get; private set; } + public bool CanProceed { get; private set; } + } +} \ No newline at end of file diff --git a/Vendor/Prise/AssemblyScanning/AssemblyScannerOptions.cs b/Vendor/Prise/AssemblyScanning/AssemblyScannerOptions.cs new file mode 100644 index 0000000..1f3acf5 --- /dev/null +++ b/Vendor/Prise/AssemblyScanning/AssemblyScannerOptions.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; + +namespace Prise.AssemblyScanning +{ + public class AssemblyScannerOptions : IAssemblyScannerOptions + { + public string StartingPath { get; set; } + + public Type PluginType { get; set; } + + public IEnumerable FileTypes { get; set; } + } +} \ No newline at end of file diff --git a/Vendor/Prise/AssemblyScanning/AssemblyScanningException.cs b/Vendor/Prise/AssemblyScanning/AssemblyScanningException.cs new file mode 100644 index 0000000..cb99aea --- /dev/null +++ b/Vendor/Prise/AssemblyScanning/AssemblyScanningException.cs @@ -0,0 +1,25 @@ +using System; +using System.Runtime.Serialization; + +namespace Prise.AssemblyScanning +{ + [Serializable] + public class AssemblyScanningException : Exception + { + public AssemblyScanningException(string message) : base(message) + { + } + + public AssemblyScanningException(string message, Exception innerException) : base(message, innerException) + { + } + + public AssemblyScanningException() + { + } + + protected AssemblyScanningException(SerializationInfo info, StreamingContext context) : base(info, context) + { + } + } +} \ No newline at end of file diff --git a/Vendor/Prise/AssemblyScanning/DefaultAssemblyResolver.cs b/Vendor/Prise/AssemblyScanning/DefaultAssemblyResolver.cs new file mode 100644 index 0000000..ce6256b --- /dev/null +++ b/Vendor/Prise/AssemblyScanning/DefaultAssemblyResolver.cs @@ -0,0 +1,68 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Runtime.Loader; +using Prise.Utils; + +namespace Prise.AssemblyScanning +{ + /// + /// This class is not tested + /// + public class DefaultAssemblyResolver : MetadataAssemblyResolver + { + private readonly string assemblyPath; + private readonly string[] platformAssemblies = new[] { "mscorlib", "netstandard", "System.Private.CoreLib", "System.Runtime" }; + + public DefaultAssemblyResolver(string fullPathToAssembly) + { + this.assemblyPath = Path.GetDirectoryName(fullPathToAssembly.ThrowIfNullOrEmpty(nameof(fullPathToAssembly))); + } + + public override Assembly Resolve(MetadataLoadContext context, AssemblyName assemblyName) + { + // We know these assemblies are located in the Host, so don't bother loading them from the plugin location + if (this.platformAssemblies.Contains(assemblyName.Name)) + { + return LoadAssemblyForRuntime(context, assemblyName); + } + + // Check if the file is found in the plugin location + var candidateFile = Path.Combine(assemblyPath, $"{assemblyName.Name}.dll"); + if (File.Exists(candidateFile)) + return context.LoadFromAssemblyPath(candidateFile); + + // Fallback, load from Host AppDomain, this is mostly required for System.* assemblies + return LoadAssemblyForRuntime(context, assemblyName); + } + + protected Assembly LoadAssemblyForRuntime(MetadataLoadContext context, AssemblyName assemblyName) + { + try + { + var candidate = GetLoadedAssemblies().FirstOrDefault(a => a.GetName().Name == assemblyName.Name); + var candidateName = candidate != null ? candidate.GetName() : null; + + if (candidateName != null && candidateName.Version != assemblyName.Version) + { + return context.LoadFromAssemblyPath(AssemblyLoadContext.Default.LoadFromAssemblyName(candidateName).Location); + } + + return context.LoadFromAssemblyPath(AssemblyLoadContext.Default.LoadFromAssemblyName(assemblyName).Location); + } + catch (FileNotFoundException) when (assemblyName?.Name == "System.Runtime") + { + var hostRuntimeAssembly = typeof(System.Runtime.GCSettings).GetTypeInfo().Assembly; + throw new AssemblyScanningException($"System.Runtime {assemblyName.Version} failed to load. Are you trying to load a new plugin into an old host? Host Runtime Version: {hostRuntimeAssembly.GetName().Version} on {hostRuntimeAssembly.CodeBase}"); + } + } + +#if SUPPORTS_LOADED_ASSEMBLIES + protected IEnumerable GetLoadedAssemblies() => AssemblyLoadContext.Default.Assemblies; +#else + protected IEnumerable GetLoadedAssemblies() => AppDomain.CurrentDomain.GetAssemblies(); +#endif + } +} \ No newline at end of file diff --git a/Vendor/Prise/AssemblyScanning/DefaultAssemblyScanner.cs b/Vendor/Prise/AssemblyScanning/DefaultAssemblyScanner.cs new file mode 100644 index 0000000..415c8a2 --- /dev/null +++ b/Vendor/Prise/AssemblyScanning/DefaultAssemblyScanner.cs @@ -0,0 +1,97 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Threading.Tasks; + +using Prise.Utils; + +namespace Prise.AssemblyScanning +{ + public class DefaultAssemblyScanner : IAssemblyScanner + { + protected IList disposables; + protected Func metadataLoadContextFactory; + protected IDirectoryTraverser directoryTraverser; + + public DefaultAssemblyScanner(Func metadataLoadContextFactory, Func directoryTraverser) + { + this.disposables = new List(); + this.metadataLoadContextFactory = metadataLoadContextFactory.ThrowIfNull(nameof(metadataLoadContextFactory)); + this.directoryTraverser = directoryTraverser.ThrowIfNull(nameof(directoryTraverser))(); + } + + public virtual Task> Scan(IAssemblyScannerOptions options) + { + if (options == null) + throw new ArgumentNullException($"{typeof(IAssemblyScannerOptions).Name} {nameof(options)}"); + + var startingPath = options.StartingPath ?? throw new ArgumentException($"{nameof(options.StartingPath)}"); + var typeToScan = options.PluginType ?? throw new ArgumentException($"{nameof(options.PluginType)}"); + var fileTypes = options.FileTypes; + + if (!Path.IsPathRooted(startingPath)) + throw new AssemblyScanningException($"startingPath {startingPath} is not rooted, this must be a absolute path!"); + + if (fileTypes == null) + fileTypes = new List { "*.dll" }; + + var results = new List(); + foreach (var directory in this.directoryTraverser.TraverseDirectories(startingPath)) + { + foreach (var assemblyFilePath in this.directoryTraverser.TraverseFiles(directory, fileTypes)) + { + foreach (var implementation in GetImplementationsOfTypeFromAssembly(typeToScan, assemblyFilePath)) + if (implementation != null) + results.Add(new AssemblyScanResult + { + ContractType = typeToScan, + AssemblyName = Path.GetFileName(assemblyFilePath), + AssemblyPath = Path.GetDirectoryName(assemblyFilePath), + PluginType = implementation + }); + } + } + + return Task.FromResult(results.AsEnumerable()); + } + + private IEnumerable ExcludeRuntimesFolder(IEnumerable files) => files.Where(f => !f.Contains($"{Path.DirectorySeparatorChar}runtimes{Path.DirectorySeparatorChar}")); + + private IEnumerable GetImplementationsOfTypeFromAssembly(Type type, string assemblyFullPath) + { + var context = this.metadataLoadContextFactory(assemblyFullPath); + var assembly = context.LoadFromAssemblyName(Path.GetFileNameWithoutExtension(assemblyFullPath)); + this.disposables.Add(context); + + return assembly.Types + .Where(t => t.CustomAttributes + .Any(c => c.AttributeType.Name == typeof(Prise.Plugin.PluginAttribute).Name + && (c.NamedArguments.First(a => a.MemberName == "PluginType").TypedValue.Value as Type).Name == type.Name + && (c.NamedArguments.First(a => a.MemberName == "PluginType").TypedValue.Value as Type).Namespace == type.Namespace)) + .OrderBy(t => t.Name) + .ToList(); + } + + protected bool disposed = false; + protected virtual void Dispose(bool disposing) + { + if (!this.disposed && disposing) + { + if (this.disposables != null && this.disposables.Any()) + foreach (var disposable in this.disposables) + disposable.Dispose(); + GC.Collect(); // collects all unused memory + GC.WaitForPendingFinalizers(); // wait until GC has finished its work + } + this.disposed = true; + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + } +} \ No newline at end of file diff --git a/Vendor/Prise/AssemblyScanning/DefaultMetadataLoadContext.cs b/Vendor/Prise/AssemblyScanning/DefaultMetadataLoadContext.cs new file mode 100644 index 0000000..e53faff --- /dev/null +++ b/Vendor/Prise/AssemblyScanning/DefaultMetadataLoadContext.cs @@ -0,0 +1,22 @@ +using System; +using System.Reflection; +using Prise.Utils; + +namespace Prise.AssemblyScanning +{ + public class DefaultMetadataLoadContext : IMetadataLoadContext + { + private readonly MetadataLoadContext loadContext; + public DefaultMetadataLoadContext(string fullPathToAssembly) + { + this.loadContext = new MetadataLoadContext(new DefaultAssemblyResolver(fullPathToAssembly.ThrowIfNullOrEmpty(nameof(fullPathToAssembly)))); + } + + public IAssemblyShim LoadFromAssemblyName(string assemblyName) => new PriseAssembly(loadContext.LoadFromAssemblyName(assemblyName)); + + public void Dispose() + { + this.loadContext?.Dispose(); + } + } +} \ No newline at end of file diff --git a/Vendor/Prise/AssemblyScanning/DefaultNugetPackageAssemblyScanner.cs b/Vendor/Prise/AssemblyScanning/DefaultNugetPackageAssemblyScanner.cs new file mode 100644 index 0000000..6250618 --- /dev/null +++ b/Vendor/Prise/AssemblyScanning/DefaultNugetPackageAssemblyScanner.cs @@ -0,0 +1,73 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading.Tasks; + +using Prise.Utils; + +namespace Prise.AssemblyScanning +{ + public class DefaultNugetPackageAssemblyScanner : DefaultAssemblyScanner, IAssemblyScanner + { + private const string ExtractedDirectoryName = "_extracted"; + + protected readonly INugetPackageUtilities nugetPackageUtilities; + + public DefaultNugetPackageAssemblyScanner( + Func metadataLoadContextFactory, + Func directoryTraverser, + Func nugetPackageUtilities) + : base(metadataLoadContextFactory, directoryTraverser) + { this.nugetPackageUtilities = nugetPackageUtilities.ThrowIfNull(nameof(nugetPackageUtilities))(); } + + public override Task> Scan(IAssemblyScannerOptions options) + { + if (options == null) + throw new ArgumentNullException($"{typeof(IAssemblyScannerOptions).Name} {nameof(options)}"); + + var startingPath = options.StartingPath ?? throw new ArgumentException($"{nameof(options.StartingPath)}"); + var typeToScan = options.PluginType ?? throw new ArgumentException($"{nameof(options.PluginType)}"); + var fileTypes = options.FileTypes; + + if (!Path.IsPathRooted(startingPath)) + throw new AssemblyScanningException($"startingPath {startingPath} is not rooted, this must be a absolute path!"); + + var packageFiles = this.nugetPackageUtilities.FindAllNugetPackagesFiles(startingPath); + + if (!packageFiles.Any()) + throw new AssemblyScanningException($"Scanning for NuGet packages had no results for Plugin Type {typeToScan.Name}"); + + var packages = new List(); + + foreach (var packageFile in packageFiles) + { + var version = this.nugetPackageUtilities.GetVersionFromPackageFile(packageFile); + var packageName = this.nugetPackageUtilities.GetPackageName(packageFile); + packages.Add(new PluginNugetPackage + { + Version = version, + FullPath = packageFile, + PackageName = packageName + }); + } + + // extract all nuget packages (if not already extracted) + foreach (var package in packages) + { + var extractedNugetDirectory = Path.Combine(startingPath, ExtractedDirectoryName, package.PackageName, package.Version.ToString()); + var hasAlreadyBeenExtracted = this.nugetPackageUtilities.HasAlreadyBeenExtracted(extractedNugetDirectory); + if(!hasAlreadyBeenExtracted) + this.nugetPackageUtilities.UnCompressNugetPackage(package.FullPath, extractedNugetDirectory); + } + + // Continue with default assembly scanning + return base.Scan(new AssemblyScannerOptions + { + StartingPath = Path.Combine(startingPath, ExtractedDirectoryName), + PluginType = typeToScan, + FileTypes = fileTypes + }); + } + } +} \ No newline at end of file diff --git a/Vendor/Prise/AssemblyScanning/DefaultNugetPackageUtilities.cs b/Vendor/Prise/AssemblyScanning/DefaultNugetPackageUtilities.cs new file mode 100644 index 0000000..db65838 --- /dev/null +++ b/Vendor/Prise/AssemblyScanning/DefaultNugetPackageUtilities.cs @@ -0,0 +1,46 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.IO.Compression; +using System.Linq; +using System.Text.RegularExpressions; +using System.Xml.Linq; + +namespace Prise.AssemblyScanning +{ + public class DefaultNugetPackageUtilities : INugetPackageUtilities + { + public IEnumerable FindAllNugetPackagesFiles(string startingPath) + { + return Directory.GetFiles(startingPath, "*.nupkg", SearchOption.AllDirectories); + } + + public Version GetVersionFromPackageFile(string packageFile) + { + return new Version(GetVersionStringForPackageFile(packageFile)); + } + + public string GetPackageName(string packageFile) + { + var packageFileName = Path.GetFileName(packageFile); + var packageNameWithoutVersion = packageFileName.Replace($".{GetVersionStringForPackageFile(packageFile)}", String.Empty); + return packageNameWithoutVersion.Split(new[] { $".nupkg" }, StringSplitOptions.RemoveEmptyEntries)[0]; + } + + public void UnCompressNugetPackage(string packageFile, string extractedNugetDirectory) + { + ZipFile.ExtractToDirectory(packageFile, extractedNugetDirectory); + } + + public bool HasAlreadyBeenExtracted(string extractedNugetDirectory) + { + return Directory.Exists(extractedNugetDirectory); + } + + private string GetVersionStringForPackageFile(string packageFile) + { + var matches = Regex.Match(packageFile, @"^(.*?)\.((?:\.?[0-9]+){3,}(?:[-a-z]+)?)\.nupkg$").Groups; + return matches[matches.Count - 1].Value; + } + } +} \ No newline at end of file diff --git a/Vendor/Prise/AssemblyScanning/IAssemblyScanner.cs b/Vendor/Prise/AssemblyScanning/IAssemblyScanner.cs new file mode 100644 index 0000000..67ed701 --- /dev/null +++ b/Vendor/Prise/AssemblyScanning/IAssemblyScanner.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; + + +namespace Prise.AssemblyScanning +{ + public interface IAssemblyScanner : IDisposable + { + Task> Scan(IAssemblyScannerOptions options); + } +} \ No newline at end of file diff --git a/Vendor/Prise/AssemblyScanning/IAssemblyScannerOptions.cs b/Vendor/Prise/AssemblyScanning/IAssemblyScannerOptions.cs new file mode 100644 index 0000000..a4b75ec --- /dev/null +++ b/Vendor/Prise/AssemblyScanning/IAssemblyScannerOptions.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; + +namespace Prise.AssemblyScanning +{ + public interface IAssemblyScannerOptions + { + string StartingPath { get; } + Type PluginType { get; } + IEnumerable FileTypes { get; } + } +} \ No newline at end of file diff --git a/Vendor/Prise/AssemblyScanning/IMetadataLoadContext.cs b/Vendor/Prise/AssemblyScanning/IMetadataLoadContext.cs new file mode 100644 index 0000000..25e2f62 --- /dev/null +++ b/Vendor/Prise/AssemblyScanning/IMetadataLoadContext.cs @@ -0,0 +1,10 @@ +using System; +using System.Reflection; + +namespace Prise.AssemblyScanning +{ + public interface IMetadataLoadContext : IDisposable + { + IAssemblyShim LoadFromAssemblyName(string assemblyName); + } +} \ No newline at end of file diff --git a/Vendor/Prise/AssemblyScanning/INugetPackageUtilities.cs b/Vendor/Prise/AssemblyScanning/INugetPackageUtilities.cs new file mode 100644 index 0000000..ecd2149 --- /dev/null +++ b/Vendor/Prise/AssemblyScanning/INugetPackageUtilities.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; + +namespace Prise.AssemblyScanning +{ + public interface INugetPackageUtilities + { + IEnumerable FindAllNugetPackagesFiles(string startingPath); + Version GetVersionFromPackageFile(string packageFile); + string GetPackageName(string packageFile); + void UnCompressNugetPackage(string packageFile, string extractedNugetDirectory); + bool HasAlreadyBeenExtracted(string extractedNugetDirectory); + } +} \ No newline at end of file diff --git a/Vendor/Prise/AssemblyScanning/PluginNugetPackage.cs b/Vendor/Prise/AssemblyScanning/PluginNugetPackage.cs new file mode 100644 index 0000000..b9ccedf --- /dev/null +++ b/Vendor/Prise/AssemblyScanning/PluginNugetPackage.cs @@ -0,0 +1,11 @@ +using System; + +namespace Prise.AssemblyScanning +{ + internal class PluginNugetPackage + { + public Version Version { get; set; } + public string FullPath { get; set; } + public string PackageName { get; set; } + } +} \ No newline at end of file diff --git a/Vendor/Prise/Caching/CachedPluginAssembly.cs b/Vendor/Prise/Caching/CachedPluginAssembly.cs new file mode 100644 index 0000000..d38ef44 --- /dev/null +++ b/Vendor/Prise/Caching/CachedPluginAssembly.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Collections.Concurrent; +using System.Linq; + +namespace Prise.Caching +{ + public class CachedPluginAssembly : ICachedPluginAssembly + { + public IAssemblyShim AssemblyShim { get; set; } + + public IEnumerable HostTypes { get; set; } + } +} \ No newline at end of file diff --git a/Vendor/Prise/Caching/DefaultScopedPluginCache.cs b/Vendor/Prise/Caching/DefaultScopedPluginCache.cs new file mode 100644 index 0000000..dbe735b --- /dev/null +++ b/Vendor/Prise/Caching/DefaultScopedPluginCache.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Collections.Concurrent; +using System.Linq; + +namespace Prise.Caching +{ + public class DefaultScopedPluginCache : IPluginCache + { + protected ConcurrentBag pluginCache; + + public DefaultScopedPluginCache() + { + this.pluginCache = new ConcurrentBag(); + } + + public void Add(IAssemblyShim pluginAssembly, IEnumerable hostTypes = null) + { + this.pluginCache.Add(new CachedPluginAssembly + { + AssemblyShim = pluginAssembly, + HostTypes = hostTypes + }); + } + + public void Remove(string assemblyName) + { + this.pluginCache = new ConcurrentBag(this.pluginCache.Where(a => a.AssemblyShim.Assembly.GetName().Name != assemblyName)); + } + + public ICachedPluginAssembly[] GetAll() => this.pluginCache.ToArray(); + } +} \ No newline at end of file diff --git a/Vendor/Prise/Caching/ICachedPluginAssembly.cs b/Vendor/Prise/Caching/ICachedPluginAssembly.cs new file mode 100644 index 0000000..a5972ca --- /dev/null +++ b/Vendor/Prise/Caching/ICachedPluginAssembly.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Collections.Concurrent; +using System.Linq; + +namespace Prise.Caching +{ + public interface ICachedPluginAssembly + { + IAssemblyShim AssemblyShim { get; } + IEnumerable HostTypes { get; } + } +} \ No newline at end of file diff --git a/Vendor/Prise/Caching/IPluginCache.cs b/Vendor/Prise/Caching/IPluginCache.cs new file mode 100644 index 0000000..ae7d4fa --- /dev/null +++ b/Vendor/Prise/Caching/IPluginCache.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Collections.Concurrent; +using System.Linq; + +namespace Prise.Caching +{ + public interface IPluginCache + { + void Add(IAssemblyShim pluginAssembly, IEnumerable hostTypes = null); + void Remove(string assemblyName); + ICachedPluginAssembly[] GetAll(); + } +} \ No newline at end of file diff --git a/Vendor/Prise/Core/AssemblyScanResult.cs b/Vendor/Prise/Core/AssemblyScanResult.cs new file mode 100644 index 0000000..de61899 --- /dev/null +++ b/Vendor/Prise/Core/AssemblyScanResult.cs @@ -0,0 +1,18 @@ +using System; + +namespace Prise +{ + public class AssemblyScanResult + { + public Type ContractType { get; set; } + + /// + /// The PluginType will be null when the platform is older than netcoreapp3.0 + /// + public Type PluginType { get; set; } + public string PluginTypeName { get; set; } + public string PluginTypeNamespace { get; set; } + public string AssemblyPath { get; set; } + public string AssemblyName { get; set; } + } +} \ No newline at end of file diff --git a/Vendor/Prise/Core/DefaultDirectoryTraverser.cs b/Vendor/Prise/Core/DefaultDirectoryTraverser.cs new file mode 100644 index 0000000..678dc91 --- /dev/null +++ b/Vendor/Prise/Core/DefaultDirectoryTraverser.cs @@ -0,0 +1,28 @@ +using System.Collections.Generic; +using System.IO; +using System.Linq; + +namespace Prise +{ + public class DefaultDirectoryTraverser : IDirectoryTraverser + { + public IEnumerable TraverseDirectories(string startingPath) + { + var directories = Directory.GetDirectories(startingPath); + if (!directories.Any()) + directories = directories.Union(new[] { startingPath }).ToArray(); + + return directories; + } + + public IEnumerable TraverseFiles(string directory, IEnumerable fileTypes) + { + return fileTypes + .SelectMany(p => Directory.GetFiles(directory, p, SearchOption.AllDirectories)) + // ExcludeRuntimesFolder + .Where(f => !f.Contains($"{Path.DirectorySeparatorChar}runtimes{Path.DirectorySeparatorChar}")); + } + + private IEnumerable ExcludeRuntimesFolder(IEnumerable files) => files.Where(f => !f.Contains($"{Path.DirectorySeparatorChar}runtimes{Path.DirectorySeparatorChar}")); + } +} \ No newline at end of file diff --git a/Vendor/Prise/Core/DefaultFileSystemUtilities.cs b/Vendor/Prise/Core/DefaultFileSystemUtilities.cs new file mode 100644 index 0000000..be6c3e5 --- /dev/null +++ b/Vendor/Prise/Core/DefaultFileSystemUtilities.cs @@ -0,0 +1,63 @@ +using System; +using System.IO; +using System.Threading.Tasks; + +namespace Prise +{ + public class DefaultFileSystemUtilities : IFileSystemUtilities + { + public bool DoesFileExist(string pathToFile) + { + return File.Exists(pathToFile); + } + + public async Task ReadFileFromDisk(string pathToFile) + { + var probingPath = EnsureFileExists(pathToFile); + var memoryStream = new MemoryStream(); + using (var stream = new FileStream(probingPath, FileMode.Open, FileAccess.Read)) + { + memoryStream.SetLength(stream.Length); + await stream.ReadAsync(memoryStream.GetBuffer(), 0, (int)stream.Length); + } + return memoryStream; + } + + public string EnsureFileExists(string pathToFile) + { + var probingPath = Path.GetFullPath(pathToFile); + if (!File.Exists(probingPath)) + throw new FileNotFoundException($"Plugin assembly does not exist in path : {probingPath}"); + return probingPath; + } + + public Stream ReadDependencyFileFromDisk(string loadPath, string pluginAssemblyName) + { + var probingPath = EnsureDependencyFileExists(loadPath, pluginAssemblyName); + var memoryStream = new MemoryStream(); + using (var stream = new FileStream(probingPath, FileMode.Open, FileAccess.Read)) + { + memoryStream.SetLength(stream.Length); + stream.Read(memoryStream.GetBuffer(), 0, (int)stream.Length); + } + return memoryStream; + } + + public byte[] ToByteArray(Stream stream) + { + stream.Position = 0; + byte[] buffer = new byte[stream.Length]; + for (int totalBytesCopied = 0; totalBytesCopied < stream.Length;) + totalBytesCopied += stream.Read(buffer, totalBytesCopied, Convert.ToInt32(stream.Length) - totalBytesCopied); + return buffer; + } + + public string EnsureDependencyFileExists(string loadPath, string pluginAssemblyName) + { + var probingPath = Path.GetFullPath(Path.Combine(loadPath, pluginAssemblyName)); + if (!File.Exists(probingPath)) + throw new FileNotFoundException($"Plugin dependency assembly does not exist in path : {probingPath}"); + return probingPath; + } + } +} \ No newline at end of file diff --git a/Vendor/Prise/Core/DefaultPluginTypeSelector.cs b/Vendor/Prise/Core/DefaultPluginTypeSelector.cs new file mode 100644 index 0000000..c9f0b36 --- /dev/null +++ b/Vendor/Prise/Core/DefaultPluginTypeSelector.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Prise +{ + public class DefaultPluginTypeSelector : IPluginTypeSelector + { + public IEnumerable SelectPluginTypes(Type type, IAssemblyShim assemblyShim) + { + return assemblyShim.Types + .Where(t => t.CustomAttributes + .Any(c => c.AttributeType.Name == typeof(Prise.Plugin.PluginAttribute).Name + && (c.NamedArguments.First(a => a.MemberName == "PluginType").TypedValue.Value as Type).Name == type.Name)) + .OrderBy(t => t.Name) + .AsEnumerable(); + } + + public IEnumerable SelectPluginTypes(IAssemblyShim assemblyShim) + { + return this.SelectPluginTypes(typeof(T), assemblyShim); + } + } +} \ No newline at end of file diff --git a/Vendor/Prise/Core/IAssemblyShim.cs b/Vendor/Prise/Core/IAssemblyShim.cs new file mode 100644 index 0000000..ad3cb8b --- /dev/null +++ b/Vendor/Prise/Core/IAssemblyShim.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Reflection; + +namespace Prise +{ + public interface IAssemblyShim + { + Assembly Assembly { get; } + IEnumerable Types { get; } + } +} \ No newline at end of file diff --git a/Vendor/Prise/Core/IDirectoryTraverser.cs b/Vendor/Prise/Core/IDirectoryTraverser.cs new file mode 100644 index 0000000..bbf9f49 --- /dev/null +++ b/Vendor/Prise/Core/IDirectoryTraverser.cs @@ -0,0 +1,10 @@ +using System.Collections.Generic; + +namespace Prise +{ + public interface IDirectoryTraverser + { + IEnumerable TraverseDirectories(string startingPath); + IEnumerable TraverseFiles(string directory, IEnumerable fileTypes); + } +} \ No newline at end of file diff --git a/Vendor/Prise/Core/IFileSystemUtilities.cs b/Vendor/Prise/Core/IFileSystemUtilities.cs new file mode 100644 index 0000000..b5eb0cb --- /dev/null +++ b/Vendor/Prise/Core/IFileSystemUtilities.cs @@ -0,0 +1,15 @@ +using System.IO; +using System.Threading.Tasks; + +namespace Prise +{ + public interface IFileSystemUtilities + { + bool DoesFileExist(string pathToFile); + Task ReadFileFromDisk(string pathToFile); + string EnsureFileExists(string pathToFile); + Stream ReadDependencyFileFromDisk(string loadPath, string pluginAssemblyName); + string EnsureDependencyFileExists(string loadPath, string pluginAssemblyName); + byte[] ToByteArray(Stream stream); + } +} \ No newline at end of file diff --git a/Vendor/Prise/Core/IPluginLoadContext.cs b/Vendor/Prise/Core/IPluginLoadContext.cs new file mode 100644 index 0000000..bbb9410 --- /dev/null +++ b/Vendor/Prise/Core/IPluginLoadContext.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using Microsoft.Extensions.DependencyInjection; + +namespace Prise +{ + public interface IPluginLoadContext + { + string FullPathToPluginAssembly { get; } + Type PluginType { get; } + IEnumerable HostTypes { get; } + IEnumerable HostAssemblies { get; } + IEnumerable DowngradableHostTypes { get; } + IEnumerable DowngradableHostAssemblies { get; } + IEnumerable RemoteTypes { get; } + NativeDependencyLoadPreference NativeDependencyLoadPreference { get; } + PluginPlatformVersion PluginPlatformVersion { get; } + IEnumerable AdditionalProbingPaths { get; } + IServiceCollection HostServices { get; } + string HostFramework { get; } + bool IgnorePlatformInconsistencies { get; } + } +} \ No newline at end of file diff --git a/Vendor/Prise/Core/IPluginTypeSelector.cs b/Vendor/Prise/Core/IPluginTypeSelector.cs new file mode 100644 index 0000000..81af9d6 --- /dev/null +++ b/Vendor/Prise/Core/IPluginTypeSelector.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Reflection; +using System.Runtime.Serialization; +using System.Text.Json; +using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; +using Prise.Plugin; +using Prise.Proxy; + +namespace Prise +{ + public interface IPluginTypeSelector + { + IEnumerable SelectPluginTypes(IAssemblyShim assemblyShim); + IEnumerable SelectPluginTypes(Type type, IAssemblyShim assemblyShim); + } +} \ No newline at end of file diff --git a/Vendor/Prise/Core/IRuntimePlatformContext.cs b/Vendor/Prise/Core/IRuntimePlatformContext.cs new file mode 100644 index 0000000..afa8233 --- /dev/null +++ b/Vendor/Prise/Core/IRuntimePlatformContext.cs @@ -0,0 +1,12 @@ +using System.Collections.Generic; + +namespace Prise +{ + public interface IRuntimePlatformContext + { + IEnumerable GetPlatformExtensions(); + IEnumerable GetPluginDependencyNames(string nameWithoutFileExtension); + IEnumerable GetPlatformDependencyNames(string nameWithoutFileExtension); + RuntimeInfo GetRuntimeInfo(); + } +} \ No newline at end of file diff --git a/Vendor/Prise/Core/NativeDependencyLoadPreference.cs b/Vendor/Prise/Core/NativeDependencyLoadPreference.cs new file mode 100644 index 0000000..84cc6e0 --- /dev/null +++ b/Vendor/Prise/Core/NativeDependencyLoadPreference.cs @@ -0,0 +1,16 @@ +namespace Prise +{ + /// + /// Sets the preferred Native Library loading strategy + /// + public enum NativeDependencyLoadPreference + { + // Native libraries will be loaded from the runtime folder on the host + // Windows: C:\Program Files\dotnet\shared\.. + // Linux: /usr/share/dotnet/shared/.. + // OSX: /usr/local/share/dotnet/shared + PreferInstalledRuntime = 0, + // Native libraries will be loaded from the remote context + PreferDependencyContext + } +} \ No newline at end of file diff --git a/Vendor/Prise/Core/PluginLoadContext.cs b/Vendor/Prise/Core/PluginLoadContext.cs new file mode 100644 index 0000000..e4673de --- /dev/null +++ b/Vendor/Prise/Core/PluginLoadContext.cs @@ -0,0 +1,59 @@ +using System; +using System.Collections.Generic; +using Microsoft.Extensions.DependencyInjection; +using Prise.Utils; + +namespace Prise +{ + public class PluginLoadContext : IPluginLoadContext + { + public PluginLoadContext(string fullPathToPluginAssembly, Type pluginType, string hostFramework) + { + this.FullPathToPluginAssembly = fullPathToPluginAssembly.ThrowIfNullOrEmpty(nameof(pluginType)); + this.PluginType = pluginType.ThrowIfNull(nameof(pluginType)); + this.HostFramework = hostFramework.ThrowIfNullOrEmpty(nameof(hostFramework)); + this.HostTypes = new List() { typeof(Prise.Plugin.PluginAttribute), typeof(Microsoft.Extensions.DependencyInjection.ServiceCollection) }; + this.HostAssemblies = new List(); + this.DowngradableHostTypes = new List() { typeof(Prise.Plugin.PluginAttribute) }; + this.DowngradableHostAssemblies = new List(); + this.RemoteTypes = new List() { pluginType }; + this.NativeDependencyLoadPreference = NativeDependencyLoadPreference.PreferInstalledRuntime; + this.IgnorePlatformInconsistencies = false; + this.PluginPlatformVersion = PluginPlatformVersion.Empty(); + this.HostServices = new ServiceCollection(); + } + + public string FullPathToPluginAssembly { get; set; } + + public Type PluginType { get; set; } + + public IEnumerable HostTypes { get; set; } + + public IEnumerable HostAssemblies { get; set; } + + public IEnumerable DowngradableHostTypes { get; set; } + + public IEnumerable DowngradableHostAssemblies { get; set; } + + public IEnumerable RemoteTypes { get; set; } + + public NativeDependencyLoadPreference NativeDependencyLoadPreference { get; set; } + + public PluginPlatformVersion PluginPlatformVersion { get; set; } + + public IRuntimePlatformContext RuntimePlatformContext { get; set; } + + public IEnumerable AdditionalProbingPaths { get; set; } + + public bool IgnorePlatformInconsistencies { get; set; } + + public string HostFramework { get; set; } + + public IServiceCollection HostServices { get; } + + public static PluginLoadContext DefaultPluginLoadContext(string fullPathToPluginAssembly, + Type pluginType, + string hostFramework) + => new PluginLoadContext(fullPathToPluginAssembly, pluginType, hostFramework); + } +} \ No newline at end of file diff --git a/Vendor/Prise/Core/PluginLoadContextExtensions.cs b/Vendor/Prise/Core/PluginLoadContextExtensions.cs new file mode 100644 index 0000000..bb3c9bc --- /dev/null +++ b/Vendor/Prise/Core/PluginLoadContextExtensions.cs @@ -0,0 +1,142 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Microsoft.Extensions.DependencyInjection; + +namespace Prise +{ + public static class PluginLoadContextExtensions + { + public static PluginLoadContext AddHostServices(this PluginLoadContext pluginLoadContext, + IServiceCollection hostServices, + IEnumerable includeTypes = null, + IEnumerable excludeTypes = null) + { + if (includeTypes == null || !includeTypes.Any()) + return pluginLoadContext; // short circuit + + var hostTypes = new List(); + var priseServices = hostServices.Where(s => IsPriseService(s.ServiceType)); + var includeServices = hostServices.Where(s => Includes(s.ServiceType, includeTypes)); + var excludeServices = hostServices.Where(s => Excludes(s.ServiceType, excludeTypes)); + + foreach (var hostService in hostServices + .Except(priseServices) + .Union(includeServices) + .Except(excludeServices)) + pluginLoadContext.AddHostService(hostService); + + return pluginLoadContext; + } + + public static PluginLoadContext AddHostService(this PluginLoadContext pluginLoadContext, Type hostServiceType, Type hostServiceImplementationType, ServiceLifetime serviceLifetime = ServiceLifetime.Scoped) + { + return pluginLoadContext.AddHostService(new ServiceDescriptor(hostServiceType, hostServiceImplementationType, serviceLifetime)); + } + + public static PluginLoadContext AddHostService(this PluginLoadContext pluginLoadContext, T implementation, ServiceLifetime serviceLifetime = ServiceLifetime.Scoped) + { + return pluginLoadContext.AddHostService(new ServiceDescriptor(typeof(T), (s) => implementation, serviceLifetime)); + } + + public static PluginLoadContext AddHostService(this PluginLoadContext pluginLoadContext, ServiceDescriptor hostService) + { + // Add the Host service to the servicecollection of the plugin + pluginLoadContext.HostServices.Add(hostService); + + return pluginLoadContext + // A host type will always live inside the host + .AddHostTypes(new[] { hostService.ServiceType }) + // The implementation type will always exist on the Host, since it will be created here + .AddHostTypes(new[] { hostService.ImplementationType ?? hostService.ImplementationInstance?.GetType() ?? hostService.ImplementationFactory?.Method.ReturnType }); + } + + public static PluginLoadContext AddHostTypes(this PluginLoadContext pluginLoadContext, IEnumerable hostTypes) + { + if (hostTypes == null || !hostTypes.Any()) + return pluginLoadContext; // short circuit + + pluginLoadContext.HostTypes = new List(pluginLoadContext.HostTypes.Union(hostTypes)); + return pluginLoadContext; + } + + public static PluginLoadContext AddHostAssemblies(this PluginLoadContext pluginLoadContext, IEnumerable assemblies) + { + if (assemblies == null || !assemblies.Any()) + return pluginLoadContext; // short circuit + + pluginLoadContext.HostAssemblies = new List(pluginLoadContext.HostAssemblies.Union(assemblies)); + return pluginLoadContext; + } + + public static PluginLoadContext AddRemoteTypes(this PluginLoadContext pluginLoadContext, IEnumerable remoteTypes) + { + if (remoteTypes == null || !remoteTypes.Any()) + return pluginLoadContext; // short circuit + + pluginLoadContext.RemoteTypes = new List(pluginLoadContext.RemoteTypes.Union(remoteTypes)); + return pluginLoadContext; + } + + public static PluginLoadContext AddDowngradableHostTypes(this PluginLoadContext pluginLoadContext, IEnumerable downgradableHostTypes) + { + if (downgradableHostTypes == null || !downgradableHostTypes.Any()) + return pluginLoadContext; // short circuit + + pluginLoadContext.DowngradableHostTypes = new List(pluginLoadContext.DowngradableHostTypes.Union(downgradableHostTypes)); + return pluginLoadContext; + } + + public static PluginLoadContext AddDowngradableHostAssemblies(this PluginLoadContext pluginLoadContext, IEnumerable assemblies) + { + if (assemblies == null || !assemblies.Any()) + return pluginLoadContext; // short circuit + + pluginLoadContext.DowngradableHostAssemblies = new List(pluginLoadContext.DowngradableHostAssemblies.Union(assemblies)); + return pluginLoadContext; + } + + public static PluginLoadContext AddAdditionalProbingPaths(this PluginLoadContext pluginLoadContext, IEnumerable additionalProbingPaths) + { + if (additionalProbingPaths == null || !additionalProbingPaths.Any()) + return pluginLoadContext; // short circuit + + pluginLoadContext.AdditionalProbingPaths = new List(pluginLoadContext.AdditionalProbingPaths.Union(additionalProbingPaths)); + return pluginLoadContext; + } + + public static PluginLoadContext SetNativeDependencyLoadPreference(this PluginLoadContext pluginLoadContext, NativeDependencyLoadPreference nativeDependencyLoadPreference) + { + pluginLoadContext.NativeDependencyLoadPreference = nativeDependencyLoadPreference; + return pluginLoadContext; + } + + public static PluginLoadContext SetPlatformVersion(this PluginLoadContext pluginLoadContext, PluginPlatformVersion pluginPlatformVersion) + { + pluginLoadContext.PluginPlatformVersion = pluginPlatformVersion; + return pluginLoadContext; + } + + public static PluginLoadContext SetRuntimePlatformContext(this PluginLoadContext pluginLoadContext, IRuntimePlatformContext runtimePlatformContext) + { + pluginLoadContext.RuntimePlatformContext = runtimePlatformContext; + return pluginLoadContext; + } + + private static bool IsPriseService(Type type) => type.Namespace.StartsWith("Prise."); + + private static bool Includes(Type type, IEnumerable includeTypes) + { + if (includeTypes == null) + return true; + return includeTypes.Contains(type); + } + + private static bool Excludes(Type type, IEnumerable excludeTypes) + { + if (excludeTypes == null) + return false; + return excludeTypes.Contains(type); + } + } +} \ No newline at end of file diff --git a/Vendor/Prise/Core/PluginPlatformVersion.cs b/Vendor/Prise/Core/PluginPlatformVersion.cs new file mode 100644 index 0000000..b6ecd0a --- /dev/null +++ b/Vendor/Prise/Core/PluginPlatformVersion.cs @@ -0,0 +1,19 @@ +using System; + +namespace Prise +{ + public class PluginPlatformVersion + { + public string Version { get; private set; } + public RuntimeType Runtime { get; private set; } + public bool IsSpecified => !String.IsNullOrEmpty(Version); + + public static PluginPlatformVersion Create(string version, RuntimeType runtime = RuntimeType.UnSpecified) => new PluginPlatformVersion + { + Version = version, + Runtime = runtime + }; + + public static PluginPlatformVersion Empty() => new PluginPlatformVersion(); + } +} \ No newline at end of file diff --git a/Vendor/Prise/Core/PriseAssembly.cs b/Vendor/Prise/Core/PriseAssembly.cs new file mode 100644 index 0000000..9f6c33b --- /dev/null +++ b/Vendor/Prise/Core/PriseAssembly.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using Prise.Utils; + +namespace Prise +{ + public class PriseAssembly : IAssemblyShim + { + public PriseAssembly(Assembly assembly) + { + this.Assembly = assembly.ThrowIfNull(nameof(assembly)); + } + + public Assembly Assembly { get; private set; } + + public IEnumerable Types + { + get + { + if (this.Assembly == null) + return Enumerable.Empty(); + + return this.Assembly.GetTypes(); + } + } + } +} \ No newline at end of file diff --git a/Vendor/Prise/Core/Runtime.cs b/Vendor/Prise/Core/Runtime.cs new file mode 100644 index 0000000..5e1d82c --- /dev/null +++ b/Vendor/Prise/Core/Runtime.cs @@ -0,0 +1,9 @@ +namespace Prise +{ + public class Runtime + { + public RuntimeType RuntimeType { get; set; } + public string Version { get; set; } + public string Location { get; set; } + } +} \ No newline at end of file diff --git a/Vendor/Prise/Core/RuntimeInfo.cs b/Vendor/Prise/Core/RuntimeInfo.cs new file mode 100644 index 0000000..0b85b92 --- /dev/null +++ b/Vendor/Prise/Core/RuntimeInfo.cs @@ -0,0 +1,9 @@ +using System.Collections.Generic; + +namespace Prise +{ + public class RuntimeInfo + { + public IEnumerable Runtimes { get; set; } + } +} \ No newline at end of file diff --git a/Vendor/Prise/Core/RuntimeType.cs b/Vendor/Prise/Core/RuntimeType.cs new file mode 100644 index 0000000..c90d724 --- /dev/null +++ b/Vendor/Prise/Core/RuntimeType.cs @@ -0,0 +1,11 @@ +namespace Prise +{ + public enum RuntimeType + { + UnSpecified = 0, + AspNetCoreAll, + AspNetCoreApp, + NetCoreApp, + WindowsDesktopApp, + } +} \ No newline at end of file diff --git a/Vendor/Prise/DefaultPluginLoader.cs b/Vendor/Prise/DefaultPluginLoader.cs new file mode 100644 index 0000000..6600e74 --- /dev/null +++ b/Vendor/Prise/DefaultPluginLoader.cs @@ -0,0 +1,178 @@ +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; +using Prise.Activation; +using Prise.AssemblyLoading; +using Prise.AssemblyScanning; +using Prise.Proxy; +using Prise.Utils; + +namespace Prise +{ + public class DefaultPluginLoader : IPluginLoader + { + private readonly IAssemblyScanner assemblyScanner; + private readonly IPluginTypeSelector pluginTypeSelector; + private readonly IAssemblyLoader assemblyLoader; + private readonly IParameterConverter parameterConverter; + private readonly IResultConverter resultConverter; + private readonly IPluginActivator pluginActivator; + protected readonly ConcurrentBag pluginContexts; + public DefaultPluginLoader( + IAssemblyScanner assemblyScanner, + IPluginTypeSelector pluginTypeSelector, + IAssemblyLoader assemblyLoader, + IParameterConverter parameterConverter, + IResultConverter resultConverter, + IPluginActivator pluginActivator) + { + this.assemblyScanner = assemblyScanner; + this.pluginTypeSelector = pluginTypeSelector; + this.assemblyLoader = assemblyLoader; + this.parameterConverter = parameterConverter; + this.resultConverter = resultConverter; + this.pluginActivator = pluginActivator; + this.pluginContexts = new ConcurrentBag(); + } + + public async Task FindPlugin(string pathToPlugin) + { + return + (await this.FindPlugins(pathToPlugin)) + .FirstOrDefault(); + } + + public async Task FindPlugin(string pathToPlugins, string plugin) + { + return + (await this.FindPlugins(pathToPlugins)) + .FirstOrDefault(p => p.AssemblyPath.Split(Path.DirectorySeparatorChar).Last().Equals(plugin)); + } + + public Task> FindPlugins(string pathToPlugins) + { + return this.assemblyScanner.Scan(new AssemblyScannerOptions + { + StartingPath = pathToPlugins, + PluginType = typeof(T) + }); + } + + public async Task LoadPlugin(AssemblyScanResult scanResult, string hostFramework = null, Action configureLoadContext = null) + { + hostFramework = hostFramework.ValueOrDefault(HostFrameworkUtils.GetHostframeworkFromHost()); + + var pathToAssembly = Path.Combine(scanResult.AssemblyPath, scanResult.AssemblyName); + var pluginLoadContext = PluginLoadContext.DefaultPluginLoadContext(pathToAssembly, typeof(T), hostFramework); + // This allows the loading of netstandard plugins + pluginLoadContext.IgnorePlatformInconsistencies = true; + + configureLoadContext?.Invoke(pluginLoadContext); + + this.pluginContexts.Add(pluginLoadContext); + + var pluginAssembly = await this.assemblyLoader.Load(pluginLoadContext); + var pluginTypes = this.pluginTypeSelector.SelectPluginTypes(pluginAssembly); + var pluginType = pluginTypes.FirstOrDefault(p => p.Name.Equals(scanResult.PluginType.Name)); + if (pluginType == null) + throw new PluginLoadException($"Did not found any plugins to load from {nameof(AssemblyScanResult)} {scanResult.AssemblyPath} {scanResult.AssemblyName}"); + + return await this.pluginActivator.ActivatePlugin(new DefaultPluginActivationOptions + { + PluginType = pluginType, + PluginAssembly = pluginAssembly, + ParameterConverter = this.parameterConverter, + ResultConverter = this.resultConverter, + HostServices = pluginLoadContext.HostServices + }); + } + + public async Task> LoadPlugins(AssemblyScanResult scanResult, string hostFramework = null, Action configureLoadContext = null) + { + var plugins = new List(); + +#if SUPPORTS_ASYNC_STREAMS + await foreach (var plugin in this.LoadPluginsAsAsyncEnumerable(scanResult, hostFramework, configureLoadContext)) +#else + foreach(var plugin in await this.LoadPluginsAsAsyncEnumerable(scanResult, hostFramework, configureLoadContext)) +#endif + plugins.Add(plugin); + + return plugins; + } + +#if SUPPORTS_ASYNC_STREAMS + public async IAsyncEnumerable LoadPluginsAsAsyncEnumerable(AssemblyScanResult scanResult, string hostFramework = null, Action configureLoadContext = null) + { +#else + public async Task> LoadPluginsAsAsyncEnumerable(AssemblyScanResult scanResult, string hostFramework = null, Action configureLoadContext = null) + { +#endif + hostFramework = hostFramework.ValueOrDefault(HostFrameworkUtils.GetHostframeworkFromHost()); + + var pathToAssembly = Path.Combine(scanResult.AssemblyPath, scanResult.AssemblyName); + var pluginLoadContext = PluginLoadContext.DefaultPluginLoadContext(pathToAssembly, typeof(T), hostFramework); + // This allows the loading of netstandard plugins + pluginLoadContext.IgnorePlatformInconsistencies = true; + + configureLoadContext?.Invoke(pluginLoadContext); + + var pluginAssembly = await this.assemblyLoader.Load(pluginLoadContext); + + this.pluginContexts.Add(pluginLoadContext); + + var pluginTypes = this.pluginTypeSelector.SelectPluginTypes(pluginAssembly); + +#if SUPPORTS_ASYNC_STREAMS + foreach (var pluginType in pluginTypes) + yield return await this.pluginActivator.ActivatePlugin(new DefaultPluginActivationOptions + { + PluginType = pluginType, + PluginAssembly = pluginAssembly, + ParameterConverter = this.parameterConverter, + ResultConverter = this.resultConverter, + HostServices = pluginLoadContext.HostServices + }); +#else + var plugins = new List(); + foreach (var pluginType in pluginTypes) + plugins.Add( await this.pluginActivator.ActivatePlugin(new DefaultPluginActivationOptions + { + PluginType = pluginType, + PluginAssembly = pluginAssembly, + ParameterConverter = this.parameterConverter, + ResultConverter = this.resultConverter, + HostServices = pluginLoadContext.HostServices + })); + return plugins; +#endif + } + + public void UnloadAll() + { + foreach (var context in this.pluginContexts) + this.assemblyLoader.Unload(context); + + this.pluginContexts.Clear(); + } + + protected bool disposed = false; + protected virtual void Dispose(bool disposing) + { + if (!this.disposed && disposing) + UnloadAll(); + + this.disposed = true; + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + } +} \ No newline at end of file diff --git a/Vendor/Prise/DependencyInjection/DefaultFactories.cs b/Vendor/Prise/DependencyInjection/DefaultFactories.cs new file mode 100644 index 0000000..68f49a7 --- /dev/null +++ b/Vendor/Prise/DependencyInjection/DefaultFactories.cs @@ -0,0 +1,50 @@ +using System; +using System.Threading.Tasks; +using Prise.Activation; +using Prise.AssemblyLoading; +using Prise.AssemblyScanning; + +using Prise.Proxy; +using Prise.Infrastructure; +using Prise.Platform; +using System.Collections.Generic; + +namespace Prise.DependencyInjection +{ + public static class DefaultFactories + { + public static Func RuntimeDefaultAssemblyContext = () => new RuntimeDefaultAssemblyContext(); + public static Func DefaultNugetPackageUtilities = () => new DefaultNugetPackageUtilities(); + public static Func DefaultPlatformAbstraction = () => new DefaultPlatformAbstraction(); + public static Func DefaultDirectoryTraverser = () => new DefaultDirectoryTraverser(); + public static Func DefaultMetadataLoadContext = (fullPathToAssembly) => new DefaultMetadataLoadContext(fullPathToAssembly); + public static Func DefaultAssemblyScanner = () => new DefaultAssemblyScanner(DefaultMetadataLoadContext, DefaultDirectoryTraverser); + public static Func DefaultNuGetAssemblyScanner = () => new DefaultNugetPackageAssemblyScanner(DefaultMetadataLoadContext, DefaultDirectoryTraverser, DefaultNugetPackageUtilities); + public static Func DefaultPluginTypeSelector = () => new DefaultPluginTypeSelector(); + public static Func DefaultParameterConverter = () => new JsonSerializerParameterConverter(); + public static Func DefaultResultConverter = () => new JsonSerializerResultConverter(); + public static Func DefaultPluginActivator = () => new DefaultPluginActivator(DefaultPluginActivationContextProvider, DefaultRemotePluginActivator, DefaultPluginProxyCreator); + public static Func DefaultPluginActivationContextProvider = () => new DefaultPluginActivationContextProvider(); + public static Func DefaultRemotePluginActivator = () => new DefaultRemotePluginActivator(DefaultBootstrapperServiceProvider, DefaultPluginServiceProvider); + public static Func, IBootstrapperServiceProvider> DefaultBootstrapperServiceProvider = (sp, hostTypes) => new DefaultBootstrapperServiceProvider(sp, hostTypes); + public static Func, IEnumerable, IPluginServiceProvider> DefaultPluginServiceProvider = (sp, hostTypes, pluginTypes) => new DefaultPluginServiceProvider(sp, hostTypes, pluginTypes); + public static Func DefaultPluginProxyCreator = () => new DefaultPluginProxyCreator(); + public static Func DefaultAssemblyLoader = () => new DefaultAssemblyLoader(DefaultAssemblyLoadContextFactory); + public static Func DefaultNativeAssemblyUnloaderFactory = () => new DefaultNativeAssemblyUnloader(); + public static Func DefaultAssemblyDependencyResolver = (p) => new DefaultAssemblyDependencyResolver(p); + public static Func DefaultFileSystemUtilities = () => new DefaultFileSystemUtilities(); + public static Func DefaultPluginDependencyContextProvider = () => new DefaultPluginDependencyContextProvider(DefaultPlatformAbstraction, DefaultRuntimePlatformContextFactory); + public static Func DefaultAssemblyLoadContextFactory = () => new DefaultAssemblyLoadContext( + DefaultNativeAssemblyUnloaderFactory, + DefaultPluginDependencyResolverFactory, + DefaultAssemblyLoadStrategyFactory, + DefaultAssemblyDependencyResolver, + DefaultFileSystemUtilities, + RuntimeDefaultAssemblyContext, + DefaultPluginDependencyContextProvider + ); + public static Func DefaultRuntimePlatformContextFactory = () => new DefaultRuntimePlatformContext(DefaultPlatformAbstraction, DefaultDirectoryTraverser); + public static Func DefaultAssemblyLoadStrategyFactory = () => new DefaultAssemblyLoadStrategy(); + public static Func DefaultPluginDependencyResolverFactory = () => new DefaultPluginDependencyResolver(DefaultRuntimePlatformContextFactory); + } +} \ No newline at end of file diff --git a/Vendor/Prise/DependencyInjection/PriseDependencyInjectionException.cs b/Vendor/Prise/DependencyInjection/PriseDependencyInjectionException.cs new file mode 100644 index 0000000..0aebf95 --- /dev/null +++ b/Vendor/Prise/DependencyInjection/PriseDependencyInjectionException.cs @@ -0,0 +1,25 @@ +using System; +using System.Runtime.Serialization; + +namespace Prise.DependencyInjection +{ + [Serializable] + public class PriseDependencyInjectionException : Exception + { + public PriseDependencyInjectionException(string message) : base(message) + { + } + + public PriseDependencyInjectionException(string message, Exception innerException) : base(message, innerException) + { + } + + public PriseDependencyInjectionException() + { + } + + protected PriseDependencyInjectionException(SerializationInfo info, StreamingContext context) : base(info, context) + { + } + } +} \ No newline at end of file diff --git a/Vendor/Prise/DependencyInjection/ServiceCollectionExtensions.cs b/Vendor/Prise/DependencyInjection/ServiceCollectionExtensions.cs new file mode 100644 index 0000000..32f8b98 --- /dev/null +++ b/Vendor/Prise/DependencyInjection/ServiceCollectionExtensions.cs @@ -0,0 +1,115 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Microsoft.Extensions.DependencyInjection; +using Prise.Activation; +using Prise.AssemblyLoading; +using Prise.AssemblyScanning; +using Prise.Proxy; + +namespace Prise.DependencyInjection +{ + public static class ServiceCollectionExtensions + { + /// + /// This bootstrapper adds the basic Prise services as well as the IPluginLoader + /// + /// The path to the directory to scan for plugins + /// A ServiceCollection that has the following types registered and ready for injection: + /// , , ,, , and + /// + public static IServiceCollection AddPrise(this IServiceCollection services, + ServiceLifetime serviceLifetime = ServiceLifetime.Scoped) + { + return services + // Add all the factories + .AddFactory(DefaultFactories.DefaultAssemblyScanner, serviceLifetime) + .AddFactory(DefaultFactories.DefaultPluginTypeSelector, serviceLifetime) + .AddFactory(DefaultFactories.DefaultParameterConverter, serviceLifetime) + .AddFactory(DefaultFactories.DefaultResultConverter, serviceLifetime) + .AddFactory(DefaultFactories.DefaultPluginActivator, serviceLifetime) + .AddFactory(DefaultFactories.DefaultAssemblyLoader, serviceLifetime) + // Add the loader + .AddService(new ServiceDescriptor(typeof(IPluginLoader), typeof(DefaultPluginLoader), serviceLifetime)) + ; + } + + /// + /// This bootstrapper adds the basic Prise services, the IPluginLoader and support to load Prise NuGet Packages + /// + /// The path to the directory to scan for plugins + /// A ServiceCollection that has the following types registered and ready for injection: + /// , , ,, , and + /// + public static IServiceCollection AddPriseNugetPackages(this IServiceCollection services, + ServiceLifetime serviceLifetime = ServiceLifetime.Scoped) + { + return services + // Add all the factories + .AddFactory(DefaultFactories.DefaultNuGetAssemblyScanner, serviceLifetime) + .AddFactory(DefaultFactories.DefaultPluginTypeSelector, serviceLifetime) + .AddFactory(DefaultFactories.DefaultParameterConverter, serviceLifetime) + .AddFactory(DefaultFactories.DefaultResultConverter, serviceLifetime) + .AddFactory(DefaultFactories.DefaultPluginActivator, serviceLifetime) + .AddFactory(DefaultFactories.DefaultAssemblyLoader, serviceLifetime) + // Add the loader + .AddService(new ServiceDescriptor(typeof(IPluginLoader), typeof(DefaultPluginLoader), serviceLifetime)) + ; + } + + /// + /// This is the bootstrapper method to register a Plugin of using Prise + /// + /// The path to start scanning for plugins + /// The framework of the host, optional + /// If , an is registered, all plugins of this type will have the same configuration. If only the first found Plugin is registered + /// A builder function that you can use configure the load context + /// The Plugin type + /// A full configured ServiceCollection that will resolve or an based on + public static IServiceCollection AddPrise(this IServiceCollection services, + Func pathToPlugin, + Func hostFramework = null, + bool allowMultiple = false, + ServiceLifetime serviceLifetime = ServiceLifetime.Scoped, + Action configureContext = null) + where T : class + { + return services + .AddPrise(serviceLifetime) // Adds the default Prise Services + .AddService(new ServiceDescriptor(allowMultiple ? typeof(IEnumerable) : typeof(T), (sp) => + { + var loader = sp.GetRequiredService(); + var scanResults = loader.FindPlugins(pathToPlugin.Invoke(sp)).Result; + if (!scanResults.Any()) + throw new PriseDependencyInjectionException($"No plugin assembly was found for plugin type {typeof(T).Name}"); + + if (!allowMultiple) // Only 1 plugin is requested + return loader.LoadPlugin(scanResults.First(), hostFramework?.Invoke(sp), configureContext).Result; + + var plugins = new List(); + foreach (var scanResult in scanResults) + plugins.AddRange(loader.LoadPlugins(scanResult, hostFramework?.Invoke(sp), configureContext).Result); + + return plugins; + }, serviceLifetime)) + ; + } + + public static IServiceCollection AddFactory(this IServiceCollection services, Func func, ServiceLifetime serviceLifetime = ServiceLifetime.Scoped) + where T : class + { + Func> factoryOfFuncT = (sp) => func; + Func factoryOfT = (sp) => sp.GetRequiredService>()() as T; + return services + .AddService(new ServiceDescriptor(typeof(Func), factoryOfFuncT, serviceLifetime)) + .AddService(new ServiceDescriptor(typeof(T), factoryOfT, serviceLifetime)); + } + + private static IServiceCollection AddService(this IServiceCollection services, ServiceDescriptor serviceDescriptor) + { + services + .Add(serviceDescriptor); + return services; + } + } +} \ No newline at end of file diff --git a/Vendor/Prise/IPluginLoader.cs b/Vendor/Prise/IPluginLoader.cs new file mode 100644 index 0000000..7487dba --- /dev/null +++ b/Vendor/Prise/IPluginLoader.cs @@ -0,0 +1,78 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace Prise +{ + public interface IPluginLoader : IDisposable + { + /// + /// Looks for the first plugin of contract type inside of the pathToPlugins directory recursively. + /// The comparison is done on the last part of the path of the plugins. + /// eg: "plugins/mypluginA" => mypluginA + /// + /// Directory to start looking for plugins + /// The plugin contract + /// A that contains all the required information in order to load the plugin. + Task FindPlugin(string pathToPlugins); + + /// + /// Looks for the first plugin of contract type inside of the pathToPlugins directory recursively. + /// The comparison is done on the last part of the path of the plugins. + /// eg: "plugins/mypluginA" => mypluginA + /// + /// Directory to start looking for plugins + /// The name of the plugin to find. eg: mypluginA + /// The plugin contract + /// A that contains all the required information in order to load the plugin. + Task FindPlugin(string pathToPlugins, string plugin); + + /// + /// Looks for all the plugins from a certain directory recursively + /// + /// Starting path to start searching plugins of contract type + /// The plugin contract + /// A List of that contains all the required information in order to load the plugins + Task> FindPlugins(string pathToPlugins); + + /// + /// Loads the first implementation of the plugin contract from the . + /// Use this if you're certain that your plugin assemblies contain only 1 plugin. + /// + /// The from the FindPlugin, FindPlugins or FindPluginsAsAsyncEnumerable method. + /// The framework from the host application, optional.--> + /// A builder function that allows you to modify the PluginLoadContext before loading the plugin<, optional./param> + /// The plugin contract + /// A fully loaded and usable plugin of type + Task LoadPlugin(AssemblyScanResult scanResult, string hostFramework = null, Action configure = null); + + /// + /// Loads all the plugins from a specific . + /// + /// The from the FindPlugin, FindPlugins or FindPluginsAsAsyncEnumerable method. + /// The framework from the host application, optional.--> + /// A builder function that allows you to modify the PluginLoadContext before loading the plugin<, optional./param> + /// The plugin contract + /// A list of fully loaded and usable plugins of type + Task> LoadPlugins(AssemblyScanResult scanResult, string hostFramework = null, Action configure = null); + +#if SUPPORTS_ASYNC_STREAMS + /// + /// See + /// This method returns an IAsyncEnumerable for you to use inside of an async foreach + /// + /// The from the FindPlugin, FindPlugins or FindPluginsAsAsyncEnumerable method. + /// The framework from the host application, optional.--> + /// A builder function that allows you to modify the PluginLoadContext before loading the plugin<, optional./param> + /// The plugin contract + /// An IAsyncEnumerable of fully loaded and usable plugins of type + IAsyncEnumerable LoadPluginsAsAsyncEnumerable(AssemblyScanResult scanResult, string hostFramework = null, Action configure = null); +#endif + + /// + /// This method unloads all previously loaded plugins from this IPluginLoader + /// + /// Void + void UnloadAll(); + } +} diff --git a/Vendor/Prise/Infrastructure/JsonSerializerParameterConverter.cs b/Vendor/Prise/Infrastructure/JsonSerializerParameterConverter.cs new file mode 100644 index 0000000..f52bd49 --- /dev/null +++ b/Vendor/Prise/Infrastructure/JsonSerializerParameterConverter.cs @@ -0,0 +1,31 @@ +using System; +using System.Text.Json; +using Prise.Proxy; + +namespace Prise.Infrastructure +{ + public class JsonSerializerParameterConverter : IParameterConverter + { + public object ConvertToRemoteType(Type localType, object value) + { + var json = JsonSerializer.Serialize(value); + return JsonSerializer.Deserialize(json, localType); + } + + protected bool disposed = false; + protected virtual void Dispose(bool disposing) + { + if (!this.disposed && disposing) + { + // Nothing to do here + } + this.disposed = true; + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + } +} \ No newline at end of file diff --git a/Vendor/Prise/Infrastructure/JsonSerializerResultConverter.cs b/Vendor/Prise/Infrastructure/JsonSerializerResultConverter.cs new file mode 100644 index 0000000..3debda3 --- /dev/null +++ b/Vendor/Prise/Infrastructure/JsonSerializerResultConverter.cs @@ -0,0 +1,25 @@ +using System; +using System.Text.Json; +using Prise.Proxy; + +namespace Prise.Infrastructure +{ + public class JsonSerializerResultConverter : ResultConverter + { + public override object Deserialize(Type localType, Type remoteType, object value) + { + // Get the local type + var resultType = localType; + // Check if the type is a Task + if (localType.BaseType == typeof(System.Threading.Tasks.Task)) + { + // Get the + resultType = localType.GenericTypeArguments[0]; + } + + return JsonSerializer.Deserialize( + JsonSerializer.Serialize(value), // First, serialize the object into a string + resultType); // Second, deserialize it using the correct type + } + } +} \ No newline at end of file diff --git a/Vendor/Prise/Platform/DefaultRuntimePlatformContext.cs b/Vendor/Prise/Platform/DefaultRuntimePlatformContext.cs new file mode 100644 index 0000000..7a364d4 --- /dev/null +++ b/Vendor/Prise/Platform/DefaultRuntimePlatformContext.cs @@ -0,0 +1,124 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +using Prise.Utils; + +namespace Prise.Platform +{ + public class DefaultRuntimePlatformContext : IRuntimePlatformContext + { + private readonly IPlatformAbstraction platformAbstraction; + private readonly IDirectoryTraverser directoryTraverser; + + public DefaultRuntimePlatformContext( + Func platformAbstractionFactory, + Func directoryTraverserFactory) + { + this.platformAbstraction = platformAbstractionFactory.ThrowIfNull(nameof(platformAbstractionFactory))(); + this.directoryTraverser = directoryTraverserFactory.ThrowIfNull(nameof(directoryTraverserFactory))(); + } + + public IEnumerable GetPlatformExtensions() => GetPlatformDependencyFileExtensions(); + + public IEnumerable GetPluginDependencyNames(string nameWithoutFileExtension) => + GetPluginDependencyFileExtensions() + .Select(ext => $"{nameWithoutFileExtension}{ext}"); + + public IEnumerable GetPlatformDependencyNames(string nameWithoutFileExtension) => + GetPlatformDependencyFileCandidates(nameWithoutFileExtension); + + public RuntimeInfo GetRuntimeInfo() + { + var runtimeBasePath = GetRuntimeBasePath(); + + var platformIndependendPath = System.IO.Path.GetFullPath(runtimeBasePath); + var runtimes = new List(); + foreach (var pathToDirectory in this.directoryTraverser.TraverseDirectories(platformIndependendPath)) + { + var runtimeName = System.IO.Path.GetFileName(pathToDirectory); // Gets the directory name + var runtimeType = ParseType(runtimeName); + foreach (var pathToVersion in this.directoryTraverser.TraverseDirectories(pathToDirectory)) + { + var runtimeVersion = System.IO.Path.GetFileName(pathToVersion); // Gets the directory name + var runtimeLocation = pathToVersion; + runtimes.Add(new Runtime + { + Version = runtimeVersion, + Location = runtimeLocation, + RuntimeType = runtimeType + }); + } + } + + return new RuntimeInfo + { + Runtimes = runtimes + }; + } + + private string GetRuntimeBasePath() + { + if (this.platformAbstraction.IsWindows()) + return "C:\\Program Files\\dotnet\\shared"; + if (this.platformAbstraction.IsLinux()) + return "/usr/share/dotnet/shared"; + if (this.platformAbstraction.IsOSX()) + return "/usr/local/share/dotnet/shared"; + throw new PlatformException($"Platform {System.Runtime.InteropServices.RuntimeInformation.OSDescription} is not supported"); + } + + private RuntimeType ParseType(string runtimeName) + { + switch (runtimeName.ToUpper()) + { + case "MICROSOFT.ASPNETCORE.ALL": return RuntimeType.AspNetCoreAll; + case "MICROSOFT.ASPNETCORE.APP": return RuntimeType.AspNetCoreApp; + case "MICROSOFT.NETCORE.APP": return RuntimeType.NetCoreApp; + case "MICROSOFT.WINDOWSDESKTOP.APP": return RuntimeType.WindowsDesktopApp; + } + throw new PlatformException($"Runtime {runtimeName} could not be parsed"); + } + + private string[] GetPluginDependencyFileExtensions() + { + return new[] + { + ".dll", + ".ni.dll", + ".exe", + ".ni.exe" + }; + } + + private string[] GetPlatformDependencyFileCandidates(string fileNameWithoutExtension) + { + if (this.platformAbstraction.IsWindows()) + return new[] { $"{fileNameWithoutExtension}.dll" }; + if (this.platformAbstraction.IsLinux()) + return new[] { + $"{fileNameWithoutExtension}.so", + $"{fileNameWithoutExtension}.so.1", + $"lib{fileNameWithoutExtension}.so", + $"lib{fileNameWithoutExtension}.so.1" }; + if (this.platformAbstraction.IsOSX()) + return new[] { + $"{fileNameWithoutExtension}.dylib", + $"lib{fileNameWithoutExtension}.dylib" }; + + throw new PlatformException($"Platform {System.Runtime.InteropServices.RuntimeInformation.OSDescription} is not supported"); + } + + private string[] GetPlatformDependencyFileExtensions() + { + if (this.platformAbstraction.IsWindows()) + return new[] { ".dll" }; + if (this.platformAbstraction.IsLinux()) + return new[] { ".so", ".so.1" }; + if (this.platformAbstraction.IsOSX()) + return new[] { ".dylib" }; + + throw new PlatformException($"Platform {System.Runtime.InteropServices.RuntimeInformation.OSDescription} is not supported"); + } + } +} \ No newline at end of file diff --git a/Vendor/Prise/Platform/IPlatformAbstraction.cs b/Vendor/Prise/Platform/IPlatformAbstraction.cs new file mode 100644 index 0000000..64af97b --- /dev/null +++ b/Vendor/Prise/Platform/IPlatformAbstraction.cs @@ -0,0 +1,18 @@ +namespace Prise.Platform +{ + public interface IPlatformAbstraction + { + bool IsLinux(); + bool IsOSX(); + bool IsWindows(); + } + + public class DefaultPlatformAbstraction : IPlatformAbstraction + { + public bool IsLinux() => System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(System.Runtime.InteropServices.OSPlatform.Linux); + + public bool IsOSX() => System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(System.Runtime.InteropServices.OSPlatform.OSX); + + public bool IsWindows() => System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(System.Runtime.InteropServices.OSPlatform.Windows); + } +} \ No newline at end of file diff --git a/Vendor/Prise/Platform/PlatformException.cs b/Vendor/Prise/Platform/PlatformException.cs new file mode 100644 index 0000000..0fc9f2a --- /dev/null +++ b/Vendor/Prise/Platform/PlatformException.cs @@ -0,0 +1,25 @@ +using System; +using System.Runtime.Serialization; + +namespace Prise.Platform +{ + [Serializable] + public class PlatformException : Exception + { + public PlatformException(string message) : base(message) + { + } + + public PlatformException(string message, Exception innerException) : base(message, innerException) + { + } + + public PlatformException() + { + } + + protected PlatformException(SerializationInfo info, StreamingContext context) : base(info, context) + { + } + } +} \ No newline at end of file diff --git a/Vendor/Prise/PluginLoadException.cs b/Vendor/Prise/PluginLoadException.cs new file mode 100644 index 0000000..dcfd863 --- /dev/null +++ b/Vendor/Prise/PluginLoadException.cs @@ -0,0 +1,13 @@ +namespace Prise +{ + [System.Serializable] + public class PluginLoadException : System.Exception + { + public PluginLoadException() { } + public PluginLoadException(string message) : base(message) { } + public PluginLoadException(string message, System.Exception inner) : base(message, inner) { } + protected PluginLoadException( + System.Runtime.Serialization.SerializationInfo info, + System.Runtime.Serialization.StreamingContext context) : base(info, context) { } + } +} \ No newline at end of file diff --git a/Vendor/Prise/Prise.csproj b/Vendor/Prise/Prise.csproj new file mode 100644 index 0000000..c34a6c3 --- /dev/null +++ b/Vendor/Prise/Prise.csproj @@ -0,0 +1,57 @@ + + + Prise + Prise + Prise, A .NET Plugin Framework! + Maarten Merken + MRKN + plugin;framework;prise;decoupling;assembly;dispatchproxy;proxy + https://raw.githubusercontent.com/merken/Prise/master/LICENSE + https://github.com/merken/Prise + https://github.com/merken/Prise.git + git + $(TargetsForTfmSpecificBuildOutput);CopyProjectReferencesToPackage + default + net9.0 + + + + + + + + + + icon.png + true + true + + + + + True + + + + + + + + + + + + + + + + + true + Prise.Proxy.dll + + + true + Prise.Plugin.dll + + + diff --git a/Vendor/Prise/Utils/HostFrameworkUtils.cs b/Vendor/Prise/Utils/HostFrameworkUtils.cs new file mode 100644 index 0000000..ba042f7 --- /dev/null +++ b/Vendor/Prise/Utils/HostFrameworkUtils.cs @@ -0,0 +1,15 @@ +using System; +using System.Reflection; +using System.Runtime.Versioning; + +namespace Prise.Utils +{ + public static class HostFrameworkUtils + { + public static string GetHostframeworkFromHost() => + Assembly.GetEntryAssembly().GetCustomAttribute()?.FrameworkName; + + public static string GetHostframeworkFromType(Type type) => + type.Assembly.GetCustomAttribute()?.FrameworkName; + } +} \ No newline at end of file diff --git a/Vendor/Prise/Utils/LinqUtils.cs b/Vendor/Prise/Utils/LinqUtils.cs new file mode 100644 index 0000000..06ab083 --- /dev/null +++ b/Vendor/Prise/Utils/LinqUtils.cs @@ -0,0 +1,16 @@ +using System.Collections.Generic; + +namespace Prise.Utils +{ + public static class LinqUtils + { + public static List AddRangeToList(this List list, IEnumerable range) + { + if (range != null) + list.AddRange(range); + return list; + } + + public static List AddToList(this List list, params T[] itemsToAdd) => list.AddRangeToList(itemsToAdd); + } +} \ No newline at end of file diff --git a/Vendor/Prise/Utils/ValidationUtils.cs b/Vendor/Prise/Utils/ValidationUtils.cs new file mode 100644 index 0000000..b1f3cd2 --- /dev/null +++ b/Vendor/Prise/Utils/ValidationUtils.cs @@ -0,0 +1,26 @@ +using System; +using System.IO; +using System.Runtime.CompilerServices; + +namespace Prise.Utils +{ + public static class ValidationUtils + { + public static T ThrowIfNull(this T obj, string name, [CallerFilePath] string filePath = "") + where T : class + { + if (obj != null) + return obj; + + throw new ArgumentNullException($"Parameter {typeof(T).Name} {name} is null for type {Path.GetFileNameWithoutExtension(Path.GetFileName(filePath))}"); + } + + public static string ThrowIfNullOrEmpty(this string str, string name, [CallerFilePath] string filePath = "") + { + if (!String.IsNullOrEmpty(str)) + return str; + + throw new ArgumentNullException($"Parameter string {name} is null or empty for type {Path.GetFileNameWithoutExtension(Path.GetFileName(filePath))}"); + } + } +} \ No newline at end of file diff --git a/Vendor/Prise/Utils/ValueUtils.cs b/Vendor/Prise/Utils/ValueUtils.cs new file mode 100644 index 0000000..c72c56d --- /dev/null +++ b/Vendor/Prise/Utils/ValueUtils.cs @@ -0,0 +1,12 @@ +namespace Prise.Utils +{ + public static class ValueUtils + { + public static string ValueOrDefault(this string value, string defaultValue) + { + if (string.IsNullOrWhiteSpace(value)) + return defaultValue; + return value; + } + } +} \ No newline at end of file