// Use the ASP.NET Core DI system to inject these dependencies public PluginLoadOptions( IPluginLogger <T> logger, IAssemblyScanner <T> assemblyScanner, ISharedServicesProvider <T> sharedServicesProvider, IPluginTypesProvider <T> pluginTypesProvider, IPluginActivationContextProvider <T> pluginActivationContextProvider, IRemotePluginActivator <T> activator, IParameterConverter parameterConverter, IResultConverter resultConverter, IPluginAssemblyLoader <T> assemblyLoader, IPluginProxyCreator <T> proxyCreator, IHostTypesProvider <T> hostTypesProvider, IRemoteTypesProvider <T> remoteTypesProvider, IRuntimePlatformContext runtimePlatformContext, IAssemblySelector <T> assemblySelector, IPluginSelector <T> pluginSelector ) { this.logger = logger; this.assemblyScanner = assemblyScanner; this.sharedServicesProvider = sharedServicesProvider; this.pluginTypesProvider = pluginTypesProvider; this.pluginActivationContextProvider = pluginActivationContextProvider; this.activator = activator; this.parameterConverter = parameterConverter; this.resultConverter = resultConverter; this.assemblyLoader = assemblyLoader; this.proxyCreator = proxyCreator; this.hostTypesProvider = hostTypesProvider; this.remoteTypesProvider = remoteTypesProvider; this.runtimePlatformContext = runtimePlatformContext; this.assemblySelector = assemblySelector; this.pluginSelector = pluginSelector; }
public PluginLoadOptionsBuilder <T> WithDefaultOptions(string pluginPath = null) { if (String.IsNullOrEmpty(pluginPath)) { pluginPath = Path.Join(GetLocalExecutionPath(), "Plugins"); } this.pluginPathProvider = new DefaultPluginPathProvider <T>(pluginPath); this.dependencyPathProvider = new DependencyPathProvider <T>(pluginPath); this.runtimePlatformContext = new RuntimePlatformContext(); this.ScanForAssemblies(composer => composer.WithDefaultOptions <DefaultAssemblyScanner <T>, DefaultAssemblyScannerOptions <T> >()); this.pluginAssemblyNameProvider = new PluginAssemblyNameProvider <T>($"{typeof(T).Name}.dll"); this.sharedServicesProvider = new DefaultSharedServicesProvider <T>(new ServiceCollection()); this.activator = new DefaultRemotePluginActivator <T>(this.sharedServicesProvider); this.proxyCreator = new PluginProxyCreator <T>(); // Use System.Text.Json in 3.0 #if NETCORE3_0 this.parameterConverter = new JsonSerializerParameterConverter(); this.resultConverter = new JsonSerializerResultConverter(); this.assemblyLoaderType = typeof(DefaultAssemblyLoaderWithNativeResolver <T>); #endif // Use Newtonsoft.Json in 2.1 #if NETCORE2_1 this.parameterConverter = new NewtonsoftParameterConverter(); this.resultConverter = new NewtonsoftResultConverter(); this.assemblyLoaderType = typeof(DefaultAssemblyLoader <T>); #endif this.assemblySelector = new DefaultAssemblySelector <T>(); this.assemblyLoadOptions = new DefaultAssemblyLoadOptions <T>( PluginPlatformVersion.Empty(), false, NativeDependencyLoadPreference.PreferInstalledRuntime); this.probingPathsProvider = new ProbingPathsProvider <T>(); var hostTypesProvider = new HostTypesProvider(); hostTypesProvider.AddHostType(typeof(Prise.Plugin.PluginAttribute)); // Add the Prise.Infrastructure assembly to the host types hostTypesProvider.AddHostType(typeof(ServiceCollection)); // Adds the BuildServiceProvider assembly to the host types this.hostTypesProvider = hostTypesProvider; var remoteTypesProvider = new RemoteTypesProvider <T>(); remoteTypesProvider.AddRemoteType(typeof(T)); // Add the contract to the remote types, so that we can have backwards compatibility this.remoteTypesProvider = remoteTypesProvider; this.pluginSelector = new DefaultPluginSelector <T>(); this.depsFileProviderType = typeof(DefaultDepsFileProvider <T>); this.pluginDependencyResolverType = typeof(DefaultPluginDependencyResolver <T>); // Typically used for downloading and storing plugins from the network, but it could be useful for caching local plugins as well this.tempPathProviderType = typeof(UserProfileTempPathProvider <T>); this.nativeAssemblyUnloaderType = typeof(DefaultNativeAssemblyUnloader); this.hostFrameworkProviderType = typeof(HostFrameworkProvider); return(this); }
public DefaultPluginActivator( Func <IPluginActivationContextProvider> pluginActivationContextProviderFactory, Func <IRemotePluginActivator> remotePluginActivatorFactory, Func <IPluginProxyCreator> proxyCreatorFactory) { this.disposables = new ConcurrentBag <IDisposable>(); this.pluginActivationContextProvider = pluginActivationContextProviderFactory.ThrowIfNull(nameof(pluginActivationContextProviderFactory))(); this.remotePluginActivator = remotePluginActivatorFactory.ThrowIfNull(nameof(remotePluginActivatorFactory))(); this.proxyCreator = proxyCreatorFactory.ThrowIfNull(nameof(proxyCreatorFactory))(); }
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 PluginLoadOptionsBuilder <T> ConfigureSharedServices(Action <IServiceCollection> sharedServices) { if (this.sharedServicesProviderType != null) { throw new PrisePluginException($"A custom {typeof(ISharedServicesProvider<T>).Name} type cannot be used in combination with {nameof(ConfigureSharedServices)}service"); } var services = new ServiceCollection(); sharedServices.Invoke(services); foreach (var sharedService in services) { this .WithHostType(sharedService.ServiceType) .WithHostType(sharedService.ImplementationType ?? sharedService.ImplementationInstance?.GetType() ?? sharedService.ImplementationFactory?.Method.ReturnType) ; // If a shared service is added, it must be a added as a host type } this.sharedServicesProvider = new DefaultSharedServicesProvider <T>(services); this.activator = new DefaultRemotePluginActivator <T>(this.sharedServicesProvider); return(this); }
public PluginLoadOptionsBuilder <T> UseHostServices( IServiceCollection hostServices, IEnumerable <Type> includeTypes = null, IEnumerable <Type> excludeTypes = null) { if (this.sharedServicesProviderType != null) { throw new PrisePluginException($"A custom {typeof(ISharedServicesProvider<T>).Name} type cannot be used in combination with {nameof(ConfigureSharedServices)}service"); } this.hostServices = new ServiceCollection(); 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 service in hostServices .Except(priseServices) .Union(includeServices) .Except(excludeServices)) { this.hostServices.Add(service); } foreach (var hostService in this.hostServices) { this // A host type will always live inside the host .WithHostType(hostService.ServiceType) // The implementation type will always exist on the Host, since it will be created here .WithHostType(hostService.ImplementationType ?? hostService.ImplementationInstance?.GetType() ?? hostService.ImplementationFactory?.Method.ReturnType) ; } this.sharedServicesProvider = new DefaultSharedServicesProvider <T>(this.hostServices, this.sharedServices); this.activator = new DefaultRemotePluginActivator <T>(this.sharedServicesProvider); return(this); }
public PluginLoadOptionsBuilder <T> ConfigureSharedServices(Action <IServiceCollection> sharedServicesConfig) { if (this.sharedServicesProviderType != null) { throw new PrisePluginException($"A custom {typeof(ISharedServicesProvider<T>).Name} type cannot be used in combination with {nameof(ConfigureSharedServices)}service"); } this.sharedServices = new ServiceCollection(); sharedServicesConfig.Invoke(this.sharedServices); foreach (var sharedService in this.sharedServices) { this // The service type must exist on the remote to support backwards compatability .WithRemoteType(sharedService.ServiceType) // The implementation type will always exist on the Host, since it will be created here .WithHostType(sharedService.ImplementationType ?? sharedService.ImplementationInstance?.GetType() ?? sharedService.ImplementationFactory?.Method.ReturnType) ; // If a shared service is added, it must be a added as a host type } this.sharedServicesProvider = new DefaultSharedServicesProvider <T>(this.hostServices, this.sharedServices); this.activator = new DefaultRemotePluginActivator <T>(this.sharedServicesProvider); return(this); }
public PluginLoadOptionsBuilder <T> ConfigureHostServices(Action <IServiceCollection> hostServicesConfig) { if (this.sharedServicesProviderType != null) { throw new PrisePluginException($"A custom {typeof(ISharedServicesProvider<T>).Name} type cannot be used in combination with {nameof(ConfigureSharedServices)}service"); } this.hostServices = new ServiceCollection(); hostServicesConfig.Invoke(this.hostServices); foreach (var hostService in this.hostServices) { this // A host type will always live inside the host .WithHostType(hostService.ServiceType) // The implementation type will always exist on the Host, since it will be created here .WithHostType(hostService.ImplementationType ?? hostService.ImplementationInstance?.GetType() ?? hostService.ImplementationFactory?.Method.ReturnType) ; } this.sharedServicesProvider = new DefaultSharedServicesProvider <T>(this.hostServices, this.sharedServices); this.activator = new DefaultRemotePluginActivator <T>(this.sharedServicesProvider); return(this); }
public PluginLoadOptionsBuilder <T> WithActivator(IRemotePluginActivator <T> activator) { this.activator = activator; return(this); }