Beispiel #1
0
 // 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);
        }
Beispiel #3
0
 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))();
 }
Beispiel #4
0
        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);
 }