public async Task CanPublishAsyncEvents() { _builder.Services.AddScoped <Adder>(); _builder.AddNotificationAsyncHandler <Notification, NotificationAsyncHandlerA>(); _builder.AddNotificationAsyncHandler <Notification, NotificationAsyncHandlerB>(); _builder.AddNotificationAsyncHandler <Notification, NotificationAsyncHandlerC>(); var provider = _builder.Services.BuildServiceProvider(); var notification = new Notification(); var aggregator = provider.GetService <IEventAggregator>(); await aggregator.PublishAsync(notification); Assert.AreEqual(A + B + C, notification.SubscriberCount); }
/// <summary> /// Adds Identity support for Umbraco members /// </summary> public static IUmbracoBuilder AddMembersIdentity(this IUmbracoBuilder builder) { IServiceCollection services = builder.Services; // check if this has already been added, we cannot add twice but both front-end and back end // depend on this so it's possible it can be called twice. var distCacheBinder = new UniqueServiceDescriptor(typeof(IMemberManager), typeof(MemberManager), ServiceLifetime.Scoped); if (builder.Services.Contains(distCacheBinder)) { return(builder); } // NOTE: We are using AddIdentity which is going to add all of the default AuthN/AuthZ configurations = OK! // This will also add all of the default identity services for our user/role types that we aren't overriding = OK! // If a developer wishes to use Umbraco Members with different AuthN/AuthZ values, like different cookie values // or authentication scheme's then they can call the default identity configuration methods like ConfigureApplicationCookie. // BUT ... if a developer wishes to use the default auth schemes for entirely separate purposes alongside Umbraco members, // then we'll probably have to change this and make it more flexible like how we do for Users. Which means booting up // identity here with the basics and registering all of our own custom services. // Since we are using the defaults in v8 (and below) for members, I think using the default for members now is OK! services.AddIdentity <MemberIdentityUser, UmbracoIdentityRole>() .AddDefaultTokenProviders() .AddUserStore <IUserStore <MemberIdentityUser>, MemberUserStore>(factory => new MemberUserStore( factory.GetRequiredService <IMemberService>(), factory.GetRequiredService <IUmbracoMapper>(), factory.GetRequiredService <IScopeProvider>(), factory.GetRequiredService <IdentityErrorDescriber>(), factory.GetRequiredService <IPublishedSnapshotAccessor>(), factory.GetRequiredService <IExternalLoginWithKeyService>(), factory.GetRequiredService <ITwoFactorLoginService>() )) .AddRoleStore <MemberRoleStore>() .AddRoleManager <IMemberRoleManager, MemberRoleManager>() .AddMemberManager <IMemberManager, MemberManager>() .AddSignInManager <IMemberSignInManager, MemberSignInManager>() .AddSignInManager <IMemberSignInManagerExternalLogins, MemberSignInManager>() .AddErrorDescriber <MembersErrorDescriber>() .AddUserConfirmation <UmbracoUserConfirmation <MemberIdentityUser> >(); builder.AddNotificationHandler <MemberDeletedNotification, DeleteExternalLoginsOnMemberDeletedHandler>(); builder.AddNotificationAsyncHandler <MemberDeletedNotification, DeleteTwoFactorLoginsOnMemberDeletedHandler>(); services.ConfigureOptions <ConfigureMemberIdentityOptions>(); services.AddScoped <IMemberUserStore>(x => (IMemberUserStore)x.GetRequiredService <IUserStore <MemberIdentityUser> >()); services.AddScoped <IPasswordHasher <MemberIdentityUser>, MemberPasswordHasher>(); services.ConfigureOptions <ConfigureSecurityStampOptions>(); services.ConfigureOptions <ConfigureMemberCookieOptions>(); services.AddUnique <IMemberExternalLoginProviders, MemberExternalLoginProviders>(); return(builder); }
public static IUmbracoBuilder AddBackOfficeCore(this IUmbracoBuilder builder) { builder.Services.AddSingleton <KeepAliveMiddleware>(); builder.Services.ConfigureOptions <ConfigureGlobalOptionsForKeepAliveMiddlware>(); builder.Services.AddSingleton <ServerVariablesParser>(); builder.Services.AddSingleton <InstallAreaRoutes>(); builder.Services.AddSingleton <BackOfficeAreaRoutes>(); builder.Services.AddSingleton <PreviewRoutes>(); builder.AddNotificationAsyncHandler <ContentCacheRefresherNotification, PreviewHubUpdater>(); builder.Services.AddSingleton <BackOfficeServerVariables>(); builder.Services.AddScoped <BackOfficeSessionIdValidator>(); builder.Services.AddScoped <BackOfficeSecurityStampValidator>(); // register back office trees // the collection builder only accepts types inheriting from TreeControllerBase // and will filter out those that are not attributed with TreeAttribute var umbracoApiControllerTypes = builder.TypeLoader.GetUmbracoApiControllers().ToList(); builder.Trees() .AddTreeControllers(umbracoApiControllerTypes.Where(x => typeof(TreeControllerBase).IsAssignableFrom(x))); builder.AddWebMappingProfiles(); builder.Services.AddUnique <IPhysicalFileSystem>(factory => { var path = "~/"; var hostingEnvironment = factory.GetRequiredService <IHostingEnvironment>(); return(new PhysicalFileSystem( factory.GetRequiredService <IIOHelper>(), hostingEnvironment, factory.GetRequiredService <ILogger <PhysicalFileSystem> >(), hostingEnvironment.MapPathContentRoot(path), hostingEnvironment.ToAbsolute(path) )); }); builder.Services.AddUnique <IIconService, IconService>(); builder.Services.AddUnique <IConflictingRouteService, ConflictingRouteService>(); builder.Services.AddSingleton <UnhandledExceptionLoggerMiddleware>(); return(builder); }
public static IUmbracoBuilder AddUnattendedInstallInstallCreateUser(this IUmbracoBuilder builder) { builder.AddNotificationAsyncHandler <UnattendedInstallNotification, CreateUnattendedUserNotificationHandler>(); return(builder); }
/// <summary> /// Adds all core Umbraco services required to run which may be replaced later in the pipeline /// </summary> public static IUmbracoBuilder AddCoreInitialServices(this IUmbracoBuilder builder) { builder .AddMainDom() .AddLogging(); builder.Services.AddSingleton <IUmbracoDatabaseFactory, UmbracoDatabaseFactory>(); builder.Services.AddSingleton(factory => factory.GetRequiredService <IUmbracoDatabaseFactory>().CreateDatabase()); builder.Services.AddSingleton(factory => factory.GetRequiredService <IUmbracoDatabaseFactory>().SqlContext); builder.NPocoMappers().Add <NullableDateMapper>(); builder.PackageMigrationPlans().Add(() => builder.TypeLoader.GetPackageMigrationPlans()); builder.Services.AddSingleton <IRuntimeState, RuntimeState>(); builder.Services.AddSingleton <IRuntime, CoreRuntime>(); builder.Services.AddSingleton <PendingPackageMigrations>(); builder.AddNotificationAsyncHandler <RuntimeUnattendedInstallNotification, UnattendedInstaller>(); builder.AddNotificationAsyncHandler <RuntimeUnattendedUpgradeNotification, UnattendedUpgrader>(); // composers builder .AddRepositories() .AddServices() .AddCoreMappingProfiles() .AddFileSystems() .AddWebAssets(); // register persistence mappers - required by database factory so needs to be done here // means the only place the collection can be modified is in a runtime - afterwards it // has been frozen and it is too late builder.Mappers().AddCoreMappers(); // register the scope provider builder.Services.AddSingleton <ScopeProvider>(); // implements both IScopeProvider and IScopeAccessor builder.Services.AddSingleton <IScopeProvider>(f => f.GetRequiredService <ScopeProvider>()); builder.Services.AddSingleton <IScopeAccessor>(f => f.GetRequiredService <ScopeProvider>()); builder.Services.AddScoped <IHttpScopeReference, HttpScopeReference>(); builder.Services.AddSingleton <IJsonSerializer, JsonNetSerializer>(); builder.Services.AddSingleton <IConfigurationEditorJsonSerializer, ConfigurationEditorJsonSerializer>(); builder.Services.AddSingleton <IMenuItemCollectionFactory, MenuItemCollectionFactory>(); // register database builder // *not* a singleton, don't want to keep it around builder.Services.AddTransient <DatabaseBuilder>(); // register manifest parser, will be injected in collection builders where needed builder.Services.AddSingleton <IManifestParser, ManifestParser>(); // register the manifest filter collection builder (collection is empty by default) builder.ManifestFilters(); builder.MediaUrlGenerators() .Add <FileUploadPropertyEditor>() .Add <ImageCropperPropertyEditor>(); builder.Services.AddSingleton <IPublishedContentTypeFactory, PublishedContentTypeFactory>(); builder.Services.AddSingleton <IShortStringHelper>(factory => new DefaultShortStringHelper(new DefaultShortStringHelperConfig().WithDefault(factory.GetRequiredService <IOptions <RequestHandlerSettings> >().Value))); builder.Services.AddSingleton <IMigrationPlanExecutor, MigrationPlanExecutor>(); builder.Services.AddSingleton <IMigrationBuilder>(factory => new MigrationBuilder(factory)); builder.AddPreValueMigrators(); builder.Services.AddSingleton <IPublishedSnapshotRebuilder, PublishedSnapshotRebuilder>(); // register the published snapshot accessor - the "current" published snapshot is in the umbraco context builder.Services.AddSingleton <IPublishedSnapshotAccessor, UmbracoContextPublishedSnapshotAccessor>(); builder.Services.AddSingleton <IVariationContextAccessor, HybridVariationContextAccessor>(); // Config manipulator builder.Services.AddSingleton <IConfigManipulator, JsonConfigManipulator>(); builder.Services.AddSingleton <RichTextEditorPastedImages>(); builder.Services.AddSingleton <BlockEditorConverter>(); // both TinyMceValueConverter (in Core) and RteMacroRenderingValueConverter (in Web) will be // discovered when CoreBootManager configures the converters. We will remove the basic one defined // in core so that the more enhanced version is active. builder.PropertyValueConverters() .Remove <SimpleTinyMceValueConverter>(); // register *all* checks, except those marked [HideFromTypeFinder] of course builder.Services.AddSingleton <IMarkdownToHtmlConverter, MarkdownToHtmlConverter>(); builder.Services.AddSingleton <IContentLastChanceFinder, ContentFinderByConfigured404>(); builder.Services.AddScoped <UmbracoTreeSearcher>(); // replace builder.Services.AddSingleton <IEmailSender, EmailSender>( services => new EmailSender( services.GetRequiredService <ILogger <EmailSender> >(), services.GetRequiredService <IOptions <GlobalSettings> >(), services.GetRequiredService <IEventAggregator>(), services.GetService <INotificationHandler <SendEmailNotification> >(), services.GetService <INotificationAsyncHandler <SendEmailNotification> >())); builder.Services.AddSingleton <IExamineManager, ExamineManager>(); builder.Services.AddScoped <ITagQuery, TagQuery>(); builder.Services.AddSingleton <IUmbracoTreeSearcherFields, UmbracoTreeSearcherFields>(); builder.Services.AddSingleton <IPublishedContentQueryAccessor, PublishedContentQueryAccessor>(); builder.Services.AddScoped <IPublishedContentQuery>(factory => { var umbCtx = factory.GetRequiredService <IUmbracoContextAccessor>(); var umbracoContext = umbCtx.GetRequiredUmbracoContext(); return(new PublishedContentQuery(umbracoContext.PublishedSnapshot, factory.GetRequiredService <IVariationContextAccessor>(), factory.GetRequiredService <IExamineManager>())); }); // register accessors for cultures builder.Services.AddSingleton <IDefaultCultureAccessor, DefaultCultureAccessor>(); builder.Services.AddSingleton <IFilePermissionHelper, FilePermissionHelper>(); builder.Services.AddSingleton <IUmbracoComponentRenderer, UmbracoComponentRenderer>(); builder.Services.AddSingleton <IBackOfficeExamineSearcher, NoopBackOfficeExamineSearcher>(); builder.Services.AddSingleton <UploadAutoFillProperties>(); builder.Services.AddSingleton <ICronTabParser, NCronTabParser>(); // Add default ImageSharp configuration and service implementations builder.Services.AddSingleton(SixLabors.ImageSharp.Configuration.Default); builder.Services.AddSingleton <IImageDimensionExtractor, ImageSharpDimensionExtractor>(); builder.Services.AddSingleton <IImageUrlGenerator, ImageSharpImageUrlGenerator>(); builder.Services.AddSingleton <PackageDataInstallation>(); builder.AddInstaller(); // Services required to run background jobs (with out the handler) builder.Services.AddSingleton <IBackgroundTaskQueue, BackgroundTaskQueue>(); return(builder); }