/// <summary>
        /// Adds tenant level caching services.
        /// </summary>
        public static BlocksCoreBuilder AddCaching(this BlocksCoreBuilder builder)
        {
            builder.ConfigureServices(services =>
            {
                services.AddTransient <ITagCache, DefaultTagCache>();
                services.AddSingleton <ISignal, Signal>();
                services.AddScoped <ICacheContextManager, CacheContextManager>();
                services.AddScoped <ICacheScopeManager, CacheScopeManager>();

                services.AddScoped <ICacheContextProvider, FeaturesCacheContextProvider>();
                services.AddScoped <ICacheContextProvider, QueryCacheContextProvider>();
                services.AddScoped <ICacheContextProvider, RolesCacheContextProvider>();
                services.AddScoped <ICacheContextProvider, RouteCacheContextProvider>();
                services.AddScoped <ICacheContextProvider, UserCacheContextProvider>();
                services.AddScoped <ICacheContextProvider, KnownValueCacheContextProvider>();

                // IMemoryCache is registered at the tenant level so that there is one instance for each tenant.
                services.AddSingleton <IMemoryCache, MemoryCache>();

                // MemoryDistributedCache needs to be registered as a singleton as it owns a MemoryCache instance.
                services.AddSingleton <IDistributedCache, MemoryDistributedCache>();
            });

            return(builder);
        }
        /// <summary>
        /// Adds tenant level deferred tasks services.
        /// </summary>
        public static BlocksCoreBuilder AddDeferredTasks(this BlocksCoreBuilder builder)
        {
            builder.ConfigureServices(services =>
            {
                services.TryAddScoped <IDeferredTaskEngine, DeferredTaskEngine>();
                services.TryAddScoped <IDeferredTaskState, HttpContextTaskState>();
            });

            return(builder);
        }
Beispiel #3
0
        private static void AddExtensionServices(BlocksCoreBuilder builder)
        {
            builder.ApplicationServices.AddSingleton <IModuleNamesProvider, AssemblyAttributeModuleNamesProvider>();
            builder.ApplicationServices.AddSingleton <IApplicationContext, ModularApplicationContext>();

            builder.ApplicationServices.AddExtensionManagerHost();

            builder.ConfigureServices(services =>
            {
                services.AddExtensionManager();
            });
        }
        /// <summary>
        /// Registers at the tenant level a set of features which are always enabled.
        /// </summary>
        public static BlocksCoreBuilder AddTenantFeatures(this BlocksCoreBuilder builder, params string[] featureIds)
        {
            builder.ConfigureServices(services =>
            {
                foreach (var featureId in featureIds)
                {
                    services.AddTransient(sp => new ShellFeature(featureId, alwaysEnabled: true));
                }
            });

            return(builder);
        }
Beispiel #5
0
        /// <summary>
        /// Adds tenant level data protection services.
        /// </summary>
        private static void AddDataProtection(BlocksCoreBuilder builder)
        {
            builder.ConfigureServices((services, serviceProvider) =>
            {
                var settings = serviceProvider.GetRequiredService <ShellSettings>();
                var options  = serviceProvider.GetRequiredService <IOptions <ShellOptions> >();

                var directory = Directory.CreateDirectory(Path.Combine(
                                                              options.Value.ShellsApplicationDataPath,
                                                              options.Value.ShellsContainerName,
                                                              settings.Name, "DataProtection-Keys"));

                // Re-register the data protection services to be tenant-aware so that modules that internally
                // rely on IDataProtector/IDataProtectionProvider automatically get an isolated instance that
                // manages its own key ring and doesn't allow decrypting payloads encrypted by another tenant.
                // By default, the key ring is stored in the tenant directory of the configured App_Data path.
                var collection = new ServiceCollection()
                                 .AddDataProtection()
                                 .PersistKeysToFileSystem(directory)
                                 .SetApplicationName(settings.Name)
                                 .Services;

                // Retrieve the implementation type of the newly startup filter registered as a singleton
                var startupFilterType = collection.FirstOrDefault(s => s.ServiceType == typeof(IStartupFilter))?.ImplementationType;

                if (startupFilterType != null)
                {
                    // Remove any previously registered data protection startup filters.
                    var descriptors = services.Where(s => s.ServiceType == typeof(IStartupFilter) &&
                                                     (s.ImplementationInstance?.GetType() == startupFilterType ||
                                                      s.ImplementationType == startupFilterType)).ToArray();

                    foreach (var descriptor in descriptors)
                    {
                        services.Remove(descriptor);
                    }
                }

                // Remove any previously registered options setups.
                services.RemoveAll <IConfigureOptions <KeyManagementOptions> >();
                services.RemoveAll <IConfigureOptions <DataProtectionOptions> >();

                services.Add(collection);
            });
        }
Beispiel #6
0
        /// <summary>
        /// Adds host and tenant level antiforgery services.
        /// </summary>
        private static void AddAntiForgery(BlocksCoreBuilder builder)
        {
            builder.ApplicationServices.AddAntiforgery();

            builder.ConfigureServices((services, serviceProvider) =>
            {
                var settings = serviceProvider.GetRequiredService <ShellSettings>();

                var tenantName   = settings.Name;
                var tenantPrefix = "/" + settings.RequestUrlPrefix;

                services.AddAntiforgery(options =>
                {
                    options.Cookie.Name = "orchantiforgery_" + tenantName;
                    options.Cookie.Path = tenantPrefix;
                });
            });
        }
Beispiel #7
0
        /// <summary>
        /// Adds host and tenant level authentication services and configuration.
        /// </summary>
        private static void AddAuthentication(BlocksCoreBuilder builder)
        {
            builder.ApplicationServices.AddAuthentication();

            builder.ConfigureServices(services =>
            {
                services.AddAuthentication();

                // IAuthenticationSchemeProvider is already registered at the host level.
                // We need to register it again so it is taken into account at the tenant level
                // because it holds a reference to an underlying dictionary, responsible of storing
                // the registered schemes which need to be distinct for each tenant.
                services.AddSingleton <IAuthenticationSchemeProvider, AuthenticationSchemeProvider>();
            })
            .Configure(app =>
            {
                app.UseAuthentication();
            });
        }
Beispiel #8
0
        public static BlocksCoreBuilder AddDataAccess(this BlocksCoreBuilder builder)
        {
            builder.ConfigureServices(services =>
            {
                services.TryAddDataProvider(name: "Sql Server", value: "SqlConnection", hasConnectionString: true,
                                            hasTablePrefix: true, isDefault: false);
                services.TryAddDataProvider(name: "Sqlite", value: "Sqlite", hasConnectionString: false,
                                            hasTablePrefix: false, isDefault: true);
                services.TryAddDataProvider(name: "MySql", value: "MySql", hasConnectionString: true,
                                            hasTablePrefix: true, isDefault: false);
                services.TryAddDataProvider(name: "Postgres", value: "Postgres", hasConnectionString: true,
                                            hasTablePrefix: true, isDefault: false);

                services.AddDbContext <DbContext, BlocksCoreDbContext>();


                services.AddScoped <IDataContext, DataContext>();
            });

            return(builder);
        }