Example #1
0
        /// <summary>
        /// Setup dependency injection for cloudscribe components
        /// </summary>
        /// <param name="services"></param>
        /// <param name="configuration"></param>
        /// <returns></returns>
        public static IServiceCollection ConfigureCloudscribeCore(this IServiceCollection services, IConfigurationRoot configuration)
        {
            services.AddCaching();
            services.AddSession();
            //services.ConfigureSession(o =>
            //{
            //    o.IdleTimeout = TimeSpan.FromSeconds(10);
            //});

            services.Configure <MultiTenantOptions>(configuration.GetSection("MultiTenantOptions"));
            services.Configure <SiteConfigOptions>(configuration.GetSection("SiteConfigOptions"));
            services.Configure <SetupOptions>(configuration.GetSection("SetupOptions"));
            services.Configure <UIOptions>(configuration.GetSection("UIOptions"));
            services.Configure <cloudscribe.Core.Web.Components.Editor.CkeditorOptions>(configuration.GetSection("CkeditorOptions"));


            services.AddScoped <cloudscribe.Core.Models.Setup.ISetupTask, cloudscribe.Core.Web.Components.EnsureInitialDataSetupTask>();
            //services.AddScoped<cloudscribe.Core.Models.Setup.ISetupStep, cloudscribe.Core.Web.Components.EnsureSiteSetupStep2>();


            //*** Database platform ****************************************************************
            // here is where you could change to use one of the other db platforms
            // we have support for MSSQL MySql, PostgreSql, Firebird, SQLite, and SqlCe
            // as of 2015-11-12 mssql, sqlite, pgsql work in dnxcore50
            // to use one of the others you would have to remove the dnxcore50 from the project.json in this project
            // add a reference for one of the other cloudscribe.Core.Repositories.dbplatform
            // and cloudscribe.DbHelpers.dbplatform packages

            // this DevOptions can override from appsettings.localoverides.json
            // making it easy to change the db platform you are working with
            DevOptions devOptions = configuration.Get <DevOptions>("DevOptions");

            switch (devOptions.DbPlatform)
            {
            // the commented ones don't work yet in dnxcore50 so we can't add them to project.json
            // without dropping dnxcore50

            //case "sqlce":

            //    services.Configure<cloudscribe.DbHelpers.SqlCe.SqlCeConnectionOptions>(configuration.GetSection("Data:SqlCeConnectionOptions"));
            //    services.TryAddScoped<ISiteRepository, cloudscribe.Core.Repositories.SqlCe.SiteRepository>();
            //    services.TryAddScoped<IUserRepository, cloudscribe.Core.Repositories.SqlCe.UserRepository>();
            //    services.TryAddScoped<IGeoRepository, cloudscribe.Core.Repositories.SqlCe.GeoRepository>();
            //    services.TryAddScoped<IDbSetup, cloudscribe.Setup.SqlCe.DbSetup>();
            //    services.TryAddScoped<IDataPlatformInfo, cloudscribe.Setup.SqlCe.DbSetup>();
            //    services.TryAddScoped<ILogRepository, cloudscribe.Logging.SqlCe.LogRepository>();
            //    services.TryAddScoped<cloudscribe.DbHelpers.SqlCe.SqlCeConnectionStringResolver, cloudscribe.DbHelpers.SqlCe.SqlCeConnectionStringResolver>();


            //    break;

            //case "firebird":

            //    services.Configure<cloudscribe.DbHelpers.ConnectionStringOptions>(configuration.GetSection("Data:Firebird:ConnectionStringOptions"));

            //    services.TryAddScoped<ISiteRepository, cloudscribe.Core.Repositories.Firebird.SiteRepository>();
            //    services.TryAddScoped<IUserRepository, cloudscribe.Core.Repositories.Firebird.UserRepository>();
            //    services.TryAddScoped<IGeoRepository, cloudscribe.Core.Repositories.Firebird.GeoRepository>();
            //    services.TryAddScoped<IDbSetup, cloudscribe.Setup.Firebird.DbSetup>();
            //    services.TryAddScoped<IDataPlatformInfo, cloudscribe.Setup.Firebird.DbSetup>();
            //    services.TryAddScoped<ILogRepository, cloudscribe.Logging.Firebird.LogRepository>();

            //    break;


            //case "mysql":

            //    services.Configure<cloudscribe.DbHelpers.ConnectionStringOptions>(configuration.GetSection("Data:MySql:ConnectionStringOptions"));

            //    services.TryAddScoped<ISiteRepository, cloudscribe.Core.Repositories.MySql.SiteRepository>();
            //    services.TryAddScoped<IUserRepository, cloudscribe.Core.Repositories.MySql.UserRepository>();
            //    services.TryAddScoped<IGeoRepository, cloudscribe.Core.Repositories.MySql.GeoRepository>();
            //    services.TryAddScoped<IDbSetup, cloudscribe.Setup.MySql.DbSetup>();
            //    services.TryAddScoped<IDataPlatformInfo, cloudscribe.Setup.MySql.DbSetup>();
            //    services.TryAddScoped<ILogRepository, cloudscribe.Logging.MySql.LogRepository>();

            //    break;

            //case "sqlite":

            //    services.Configure<cloudscribe.DbHelpers.SQLite.SqliteConnectionOptions>(configuration.GetSection("Data:SqliteConnectionOptions"));


            //    services.TryAddScoped<ISiteRepository, cloudscribe.Core.Repositories.SQLite.SiteRepository>();
            //    services.TryAddScoped<IUserRepository, cloudscribe.Core.Repositories.SQLite.UserRepository>();
            //    services.TryAddScoped<IGeoRepository, cloudscribe.Core.Repositories.SQLite.GeoRepository>();
            //    services.TryAddScoped<IDbSetup, cloudscribe.Setup.Sqlite.DbSetup>();
            //    services.TryAddScoped<IDataPlatformInfo, cloudscribe.Setup.Sqlite.DbSetup>();
            //    services.TryAddScoped<ILogRepository, cloudscribe.Logging.Sqlite.LogRepository>();
            //    services.TryAddScoped<cloudscribe.DbHelpers.SQLite.SqliteConnectionstringResolver, cloudscribe.DbHelpers.SQLite.SqliteConnectionstringResolver>();

            //    break;


            //case "pgsql":

            //    services.Configure<cloudscribe.DbHelpers.ConnectionStringOptions>(configuration.GetSection("Data:PostgreSql:ConnectionStringOptions"));

            //    services.TryAddScoped<ISiteRepository, cloudscribe.Core.Repositories.pgsql.SiteRepository>();
            //    services.TryAddScoped<IUserRepository, cloudscribe.Core.Repositories.pgsql.UserRepository>();
            //    services.TryAddScoped<IGeoRepository, cloudscribe.Core.Repositories.pgsql.GeoRepository>();
            //    services.TryAddScoped<IDbSetup, cloudscribe.Setup.pgsql.DbSetup>();
            //    services.TryAddScoped<IDataPlatformInfo, cloudscribe.Setup.pgsql.DbSetup>();
            //    services.TryAddScoped<ILogRepository, cloudscribe.Logging.pgsql.LogRepository>();

            //    break;

            //case "mssql":

            //services.Configure<cloudscribe.DbHelpers.MSSQLConnectionOptions>(configuration.GetSection("Data:MSSQLConnectionOptions"));
            //services.TryAddScoped<ISiteRepository, cloudscribe.Core.Repositories.MSSQL.SiteRepository>();
            //services.TryAddScoped<IUserRepository, cloudscribe.Core.Repositories.MSSQL.UserRepository>();
            //services.TryAddScoped<IGeoRepository, cloudscribe.Core.Repositories.MSSQL.GeoRepository>();
            //services.TryAddScoped<IDbSetup, cloudscribe.Setup.MSSQL.DbSetup>();
            //services.TryAddScoped<IDataPlatformInfo, cloudscribe.Setup.MSSQL.DbSetup>();
            //services.TryAddScoped<ILogRepository, cloudscribe.Logging.MSSQL.LogRepository>();

            case "ef7":

                services.TryAddScoped <ICoreModelMapper, SqlServerCoreModelMapper>();
                services.TryAddScoped <cloudscribe.Logging.EF.ILogModelMapper, cloudscribe.Logging.EF.SqlServerLogModelMapper>();

                services.AddEntityFramework()
                .AddSqlServer()
                .AddDbContext <CoreDbContext>(options =>
                                              options.UseSqlServer(configuration["Data:EF7ConnectionOptions:ConnectionString"])
                                              // this is needed if you use sqlserver 2008
                                              // .UseRowNumberForPaging()

                                              )
                .AddDbContext <cloudscribe.Logging.EF.LoggingDbContext>(options =>
                                                                        options.UseSqlServer(configuration["Data:EF7ConnectionOptions:ConnectionString"])
                                                                        );

                services.TryAddScoped <ISiteRepository, cloudscribe.Core.Repositories.EF.SiteRepository>();
                services.TryAddScoped <IUserRepository, cloudscribe.Core.Repositories.EF.UserRepository>();
                services.TryAddScoped <IGeoRepository, cloudscribe.Core.Repositories.EF.GeoRepository>();
                services.TryAddScoped <IDataPlatformInfo, cloudscribe.Core.Repositories.EF.DataPlatformInfo>();

                services.TryAddScoped <ILogRepository, cloudscribe.Logging.EF.LogRepository>();


                break;
            }


            //**************************************************************************************

            // RequestSiteResolver resolves ISiteSettings based on the request to support multi tenancy based on either host name or first folder depending on configuration
            //services.TryAddScoped<ISiteResolver, RequestSiteResolver>();
            services.TryAddScoped <ITimeZoneResolver, RequestTimeZoneResolver>();

            //services.AddMultitenancy<SiteSettings, SiteResolver>();
            services.AddMultitenancy <SiteSettings, CachingSiteResolver>();


            services.TryAddScoped <SiteManager, SiteManager>();
            services.TryAddScoped <SetupManager, SetupManager>();
            services.TryAddScoped <GeoDataManager, GeoDataManager>();
            services.TryAddScoped <SystemInfoManager, SystemInfoManager>();
            services.TryAddScoped <IpAddressTracker, IpAddressTracker>();

            //

            services.TryAddScoped <SiteDataProtector, SiteDataProtector>();

            // VersionProviders are used by the Setup controller to determine what install and upgrade scripts to run
            services.AddScoped <IVersionProvider, SetupVersionProvider>();
            services.AddScoped <IVersionProvider, CloudscribeCoreVersionProvider>();
            services.AddScoped <IVersionProvider, cloudscribe.Logging.Web.CloudscribeLoggingVersionProvider>();

            // the factory will provide access to the previously registered IVersionProviders
            services.TryAddScoped <IVersionProviderFactory, VersionProviderFactory>();

            services.AddCloudscribeIdentity <SiteUser, SiteRole>()
            .AddDefaultTokenProviders();

            // you can use either json or xml to maintain your navigation map we provide examples of each navigation.xml and
            // navigation.json in the root of this project
            // you can override the name of the file used with AppSettings:NavigationXmlFileName or AppSettings:NavigationJsonFileName in config.json
            // the file must live in the root of the web project code not in wwwroot

            // it is arguable which is easier for humans to read and maintain, myself I think for something like a navigation tree
            // that could get large xml is easier to work with and not make mistakes. in json one missing or extra comma can break it
            // granted xml can be broken by typos too but the end tags make it easier to keep track of where you are imho (JA)
            //services.TryAddScoped<INavigationTreeBuilder, JsonNavigationTreeBuilder>();
            //services.TryAddScoped<INavigationTreeBuilder, HardCodedNavigationTreeBuilder>();
            services.TryAddScoped <ITreeCache, MemoryTreeCache>();
            services.AddScoped <INavigationTreeBuilder, XmlNavigationTreeBuilder>();
            services.AddScoped <NavigationTreeBuilderService, NavigationTreeBuilderService>();
            services.TryAddScoped <INodeUrlPrefixProvider, FolderTenantNodeUrlPrefixProvider>();
            services.TryAddScoped <INavigationNodePermissionResolver, NavigationNodePermissionResolver>();
            services.Configure <NavigationOptions>(configuration.GetSection("NavigationOptions"));


            services.TryAddTransient <IBuildPaginationLinks, PaginationLinkBuilder>();


            //services.AddTransient<IEmailTemplateService, HardCodedEmailTemplateService>();
            services.AddTransient <ISiteMessageEmailSender, SiteEmailMessageSender>();
            services.AddTransient <ISmsSender, SiteSmsSender>();

            services.TryAddSingleton <IThemeListBuilder, SiteThemeListBuilder>();


            services.TryAddSingleton <IRazorViewEngine, CoreViewEngine>();
            // cloudscribe.Core.Web.CoreViewEngine adds /Views/Sys as the last place to search for views
            // cloudscribe views are all under Views/Sys
            // to modify a view just copy it to a higher priority location
            // ie copy /Views/Sys/Manage/*.cshtml up to /Views/Manage/ and that one will have higher priority
            // and you can modify it however you like
            // upgrading to newer versions of cloudscribe could modify or add views below /Views/Sys
            // so you may need to compare your custom views to the originals again after upgrades

            // Add MVC services to the services container.
            services.AddMvc(options =>
            {
                //options.Filters.Add(...);
            })
            .AddViewLocalization(options => options.ResourcesPath = "AppResources")
            //.AddDataAnnotationsLocalization()
            //.AddXmlDataContractSerializerFormatters()
            .AddViewOptions(options =>
            {
            });

            services.Configure <RazorViewEngineOptions>(options =>
            {
                options.ViewLocationExpanders.Add(new SiteViewLocationExpander());
            });



            //https://github.com/aspnet/Announcements/issues/71

            // Configure the options for the authentication middleware.
            // You can add options for Google, Twitter and other middleware as shown below.
            // For more information see http://go.microsoft.com/fwlink/?LinkID=532715
            // establish AppId and AppSecret here https://developers.facebook.com/apps
            // https://github.com/aspnet/Security/blob/dev/src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationOptions.cs
            //services.Configure<FacebookAuthenticationOptions>(options =>
            //{
            //    // options here are only used if not specified in site settings
            //    options.AppId = configuration["Authentication:Facebook:AppId"];
            //    options.AppSecret = configuration["Authentication:Facebook:AppSecret"];
            //    //options.AuthenticationScheme = AuthenticationScheme.External;

            //});

            //// get clientid and secret here https://account.live.com/developers/applications/index
            //services.Configure<MicrosoftAccountAuthenticationOptions>(options =>
            //{
            //    options.ClientId = configuration["Authentication:MicrosoftAccount:ClientId"];
            //    options.ClientSecret = configuration["Authentication:MicrosoftAccount:ClientSecret"];
            //});

            ////https://auth0.com/docs/connections/social/google
            //// get clientid and secret here https://console.developers.google.com/
            //services.Configure<GoogleAuthenticationOptions>(options =>
            //{
            //    options.ClientId = configuration["Authentication:Google:ClientId"];
            //    options.ClientSecret = configuration["Authentication:Google:ClientSecret"];
            //});


            //// get consumerkey and secret here https://apps.twitter.com/
            //// unlike the other providers twitter does not allow creating localhost apps for testing
            //// but you can use an url shortener to mask the localhost urls
            //services.Configure<TwitterAuthenticationOptions>(options =>
            //{
            //    options.ConsumerKey = configuration["Authentication:Twitter:ConsumerKey"];
            //    options.ConsumerSecret = configuration["Authentication:Twitter:ConsumerSecret"];
            //});

            return(services);
        }
Example #2
0
        // Configure is called after ConfigureServices is called.
        // you can change this method signature to include any dependencies that need to be injected into this method
        // you can see we added the dependency for IOptions<MultiTenantOptions>
        // so basically if you need any service in this method that was previously setup in ConfigureServices
        // you can just add it to the method signature and it will be provided by dependency injection
        public void Configure(
            IApplicationBuilder app,
            IHostingEnvironment env,
            ILoggerFactory loggerFactory,
            IOptions <MultiTenantOptions> multiTenantOptions,
            IServiceProvider serviceProvider,
            ILogRepository logRepository)
        {
            // Configure the HTTP request pipeline.

            //http://blog.getglimpse.com/2015/11/19/installing-glimpse-v2-beta1/
            bool enableGlimpse = Configuration.Get <bool>("DiagnosticOptions:EnableGlimpse", false);

            if (enableGlimpse)
            {
                app.UseGlimpse();
            }


            // LogLevels
            //Debug = 1,
            //Trace = 2,
            //Information = 3,
            //Warning = 4,
            //Error = 5,
            //Critical = 6,

            // Add the console logger.
            loggerFactory.AddConsole(minLevel: LogLevel.Warning);

            // a customizable filter for logging
            LogLevel      minimumLevel    = LogLevel.Warning;
            List <string> excludedLoggers = new List <string>();

            // add exclusions to remove noise in the logs

            // we need to filter out EF otherwise each time we persist a log item to the db more logs are generated
            // so it can become an infinite loop that keeps creating data
            // you can add any loggers that you want to exclude to reduce noise in the log
            excludedLoggers.Add("Microsoft.Data.Entity.Storage.Internal.RelationalCommandBuilderFactory");
            excludedLoggers.Add("Microsoft.Data.Entity.Query.Internal.QueryCompiler");
            excludedLoggers.Add("Microsoft.Data.Entity.DbContext");

            Func <string, LogLevel, bool> logFilter = delegate(string loggerName, LogLevel logLevel)
            {
                if (logLevel < minimumLevel)
                {
                    return(false);
                }
                if (excludedLoggers.Contains(loggerName))
                {
                    return(false);
                }

                return(true);
            };

            // Add cloudscribe db logging
            loggerFactory.AddDbLogger(serviceProvider, logRepository, logFilter);



            //app.UseCultureReplacer();

            // localization from .resx files is not really working in beta8
            // will have to wait till next release

            var supportedCultures = new[]
            {
                new CultureInfo("en-US"),
                new CultureInfo("it"),
                new CultureInfo("fr-FR")
            };

            var locOptions = new RequestLocalizationOptions
            {
                // You must explicitly state which cultures your application supports.
                // These are the cultures the app supports for formatting numbers, dates, etc.
                SupportedCultures   = supportedCultures,
                SupportedUICultures = supportedCultures
            };

            // You can change which providers are configured to determine the culture for requests, or even add a custom
            // provider with your own logic. The providers will be asked in order to provide a culture for each request,
            // and the first to provide a non-null result that is in the configured supported cultures list will be used.
            // By default, the following built-in providers are configured:
            // - QueryStringRequestCultureProvider, sets culture via "culture" and "ui-culture" query string values, useful for testing
            // - CookieRequestCultureProvider, sets culture via "ASPNET_CULTURE" cookie
            // - AcceptLanguageHeaderRequestCultureProvider, sets culture via the "Accept-Language" request header
            //locOptions.RequestCultureProviders.Insert(0, new CustomRequestCultureProvider(async context =>
            //{
            //  // My custom request culture logic
            //  return new ProviderCultureResult("en");
            //}));
            //app.UseRequestLocalization(locOptions,
            //    defaultRequestCulture: new RequestCulture(culture: "en-US", uiCulture: "en-US"));


            // Add the following to the request pipeline only in development environment.
            if (env.IsEnvironment("Development"))
            {
                //app.UseBrowserLink();

                app.UseDeveloperExceptionPage();

                //app.UseDatabaseErrorPage(DatabaseErrorPageOptions.ShowAll);
                //app.UseStatusCodePagesWithReExecute("/error/{0}");
                //app.UseStatusCodePagesWithReExecute("/error/{0}");
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");

                // handle 404 and other non success
                //app.UseStatusCodePages();

                // app.UseStatusCodePages(context => context.HttpContext.Response.SendAsync("Handler, status code: " + context.HttpContext.Response.StatusCode, "text/plain"));
                // app.UseStatusCodePages("text/plain", "Response, status code: {0}");
                // app.UseStatusCodePagesWithRedirects("~/errors/{0}"); // PathBase relative
                // app.UseStatusCodePagesWithRedirects("/base/errors/{0}"); // Absolute
                // app.UseStatusCodePages(builder => builder.UseWelcomePage());
                //app.UseStatusCodePagesWithReExecute("/errors/{0}");
                //app.UseStatusCodePagesWithReExecute("/error/{0}");
            }

            // Add the platform handler to the request pipeline.
            //app.UseIISPlatformHandler();
            app.UseIISPlatformHandler(options => options.AuthenticationDescriptions.Clear());

            //app.UseRuntimeInfoPage("/info");

            // Add static files to the request pipeline.
            app.UseStaticFiles();

            // the only thing we are using session for is Alerts
            app.UseSession();
            //app.UseInMemorySession(configure: s => s.IdleTimeout = TimeSpan.FromMinutes(20));

            app.UseMultitenancy <SiteSettings>();

            // this is in Startup.CloudscribeCore.cs
            app.UseCloudscribeCore(multiTenantOptions, Configuration);

            // it is very important that all authentication configuration be set before configuring mvc
            // ie if app.UseFacebookAuthentication(); was below app.UseMvc the facebook login button will not be shown


            // Add MVC to the request pipeline.
            app.UseMvc(routes =>
            {
                // Understanding ASP.NET Routing:

                // it is very important that routes are registered in the correct order. more specific routes must be registered first and
                // less specific routes must be registered later. a request may match more than one route.

                // When a request comes in it is compared to routes in the route table and the first route it matches is used no matter if a
                // better match exists. therefore if a less specific route is registered first it will catch requests that would have a better
                // match with a more specific route that was registered later.

                // ie the default route is usually the least specific route and must be registered last

                // something like a route for a cms would likely need to be the default route added last especially if you are not going to use
                // a controller segment in the route because without a controller segment the route is less specific


                // default route for folder sites must be second to last
                if (multiTenantOptions.Value.Mode == MultiTenantMode.FolderName)
                {
                    routes.MapRoute(
                        name: "folderdefault",
                        template: "{sitefolder}/{controller}/{action}/{id?}",
                        defaults: new { controller = "Home", action = "Index" },
                        constraints: new { name = new SiteFolderRouteConstraint() }
                        );
                }


                // the default route has to be added last
                routes.MapRoute(
                    name: "default",
                    template: "{controller}/{action}/{id?}",
                    defaults: new { controller = "Home", action = "Index" }
                    );

                // Uncomment the following line to add a route for porting Web API 2 controllers.
                // routes.MapWebApiRoute("DefaultApi", "api/{controller}/{id?}");
            })
            ;

            // https://github.com/aspnet/Announcements/issues/54
            // if you want to run the IIS pipeline for requests not handled
            // ie you won't see the IIS 404 page without this.
            // if nothing else handles the 404 then you get a blank white page in the browser
            //app.RunIISPipeline();

            //app.Run(context =>
            //{
            //    context.Response.StatusCode = 404;
            //    return Task.FromResult(0);
            //});

            DevOptions devOptions = Configuration.Get <DevOptions>("DevOptions");

            if (devOptions.DbPlatform == "ef7")
            {
                cloudscribe.Core.Repositories.EF.InitialData.InitializeDatabaseAsync(app.ApplicationServices).Wait();
                // this is using EF for the logger but using EF for Core does not mean you must use EF for logging
                // one should be able to use the MSSQL Logger while still using EF for the core repos
                // one problem with EF logging is that EF logs a lot of information stuff and if we use EF for logigng
                // then every time a log item is inserted to the db it generates more logging events
                // and thus a continuous creation of data can result so the EF logger is designed to leave out
                // EF components from logging
                // by using the mssql logger instead then no extra log items will be created and you can more easily allow
                // EF to log things of its own
                // however the mssql logger depends on the setup system which is not used by EF components
                // this dependency is more practical than technical though, you could run the db setup script for mssql logging
                // manually instead of using the setup system.
                cloudscribe.Logging.EF.DbInitializer.InitializeDatabaseAsync(app.ApplicationServices).Wait();
            }
        }