public void TryAddIfMissingActuallyAdds() { // Arrange var collection = new ServiceCollection(); var d = ServiceDescriptor.Transient <IFakeService, FakeService>(); // Act collection.TryAdd(d); // Assert var descriptor = Assert.Single(collection); Assert.Equal(typeof(IFakeService), descriptor.ServiceType); Assert.Null(descriptor.ImplementationInstance); Assert.Equal(ServiceLifetime.Transient, descriptor.Lifetime); }
public void TryAddNoOpFailsIfExists(Action <IServiceCollection> addAction) { // Arrange var collection = new ServiceCollection(); addAction(collection); var d = ServiceDescriptor.Transient <IFakeService, FakeService>(); // Act collection.TryAdd(d); // Assert var descriptor = Assert.Single(collection); Assert.Equal(typeof(IFakeService), descriptor.ServiceType); Assert.Same(_instance, descriptor.ImplementationInstance); Assert.Equal(ServiceLifetime.Singleton, descriptor.Lifetime); }
public void TryAddWithEnumerableReturnsTrueIfAnyAdded() { // Arrange var collection = new ServiceCollection(); // Act var ds = new IServiceDescriptor[] { new ServiceDescriber().Transient <IFakeService, FakeService>(), new ServiceDescriber().Transient <IFakeService, FakeService>() }; // Assert Assert.True(collection.TryAdd(ds)); var descriptor = Assert.Single(collection); Assert.Equal(typeof(IFakeService), descriptor.ServiceType); Assert.Null(descriptor.ImplementationInstance); Assert.Equal(LifecycleKind.Transient, descriptor.Lifecycle); }
public void TryAddWithEnumerableReturnsFalseIfNoneAdded() { // Arrange var collection = new ServiceCollection(); collection.AddSingleton <IFakeService, FakeService>(); // Act var ds = new ServiceDescriptor[] { ServiceDescriptor.Transient <IFakeService, FakeService>(), ServiceDescriptor.Transient <IFakeService, FakeService>() }; // Assert Assert.False(collection.TryAdd(ds)); var descriptor = Assert.Single(collection); Assert.Equal(typeof(IFakeService), descriptor.ServiceType); Assert.Null(descriptor.ImplementationInstance); Assert.Equal(ServiceLifetime.Singleton, descriptor.Lifetime); }
public void TryAddNoOpFailsIfExists(Action<IServiceCollection> addAction) { // Arrange var collection = new ServiceCollection(); addAction(collection); var d = ServiceDescriptor.Transient<IFakeService, FakeService>(); // Act collection.TryAdd(d); // Assert var descriptor = Assert.Single(collection); Assert.Equal(typeof(IFakeService), descriptor.ServiceType); Assert.Same(_instance, descriptor.ImplementationInstance); Assert.Equal(ServiceLifetime.Singleton, descriptor.Lifetime); }
public void TryAddIfMissingActuallyAdds() { // Arrange var collection = new ServiceCollection(); var d = ServiceDescriptor.Transient<IFakeService, FakeService>(); // Act collection.TryAdd(d); // Assert var descriptor = Assert.Single(collection); Assert.Equal(typeof(IFakeService), descriptor.ServiceType); Assert.Null(descriptor.ImplementationInstance); Assert.Equal(ServiceLifetime.Transient, descriptor.Lifetime); }
public void TryAddWithEnumerableReturnsTrueIfAnyAdded() { // Arrange var collection = new ServiceCollection(); // Act var ds = new ServiceDescriptor[] { ServiceDescriptor.Transient<IFakeService, FakeService>(), ServiceDescriptor.Transient<IFakeService, FakeService>() }; // Assert Assert.True(collection.TryAdd(ds)); var descriptor = Assert.Single(collection); Assert.Equal(typeof(IFakeService), descriptor.ServiceType); Assert.Null(descriptor.ImplementationInstance); Assert.Equal(ServiceLifetime.Transient, descriptor.Lifetime); }
public static IServiceCollection GetDefaultServices() { var services = new ServiceCollection(); // Options and core services. services.AddTransient<IConfigureOptions<MvcOptions>, MvcOptionsSetup>(); services.AddTransient<IConfigureOptions<RazorViewEngineOptions>, RazorViewEngineOptionsSetup>(); // TryAdd() so functional tests can override this particular service. Test setup runs before this method. services.TryAdd(ServiceDescriptor.Transient<IAssemblyProvider, DefaultAssemblyProvider>()); services.AddTransient<MvcMarkerService, MvcMarkerService>(); services.AddSingleton<ITypeActivatorCache, DefaultTypeActivatorCache>(); services.AddScoped(typeof(IScopedInstance<>), typeof(ScopedInstance<>)); // Core action discovery, filters and action execution. // These are consumed only when creating action descriptors, then they can be de-allocated services.AddTransient<IControllerTypeProvider, DefaultControllerTypeProvider>(); services.AddTransient<IControllerModelBuilder, DefaultControllerModelBuilder>(); services.AddTransient<IActionModelBuilder, DefaultActionModelBuilder>(); // This has a cache, so it needs to be a singleton services.AddSingleton<IControllerFactory, DefaultControllerFactory>(); services.AddTransient<IControllerActivator, DefaultControllerActivator>(); // This accesses per-reqest services services.AddTransient<IActionInvokerFactory, ActionInvokerFactory>(); // This provider needs access to the per-request services, but might be used many times for a given // request. services.AddTransient<IActionConstraintProvider, DefaultActionConstraintProvider>(); services.AddSingleton<IActionSelectorDecisionTreeProvider, ActionSelectorDecisionTreeProvider>(); services.AddSingleton<IActionSelector, DefaultActionSelector>(); services.AddTransient<IControllerActionArgumentBinder, DefaultControllerActionArgumentBinder>(); services.AddTransient<IObjectModelValidator, DefaultObjectValidator>(); services.AddTransient<IActionDescriptorProvider, ControllerActionDescriptorProvider>(); services.AddTransient<IActionInvokerProvider, ControllerActionInvokerProvider>(); services.AddSingleton<IActionDescriptorsCollectionProvider, DefaultActionDescriptorsCollectionProvider>(); // The IGlobalFilterProvider is used to build the action descriptors (likely once) and so should // remain transient to avoid keeping it in memory. services.AddTransient<IGlobalFilterProvider, DefaultGlobalFilterProvider>(); services.AddTransient<IFilterProvider, DefaultFilterProvider>(); services.AddTransient<FormatFilter, FormatFilter>(); services.AddTransient<CorsAuthorizationFilter, CorsAuthorizationFilter>(); // Dataflow - ModelBinding, Validation and Formatting // // The DefaultModelMetadataProvider does significant caching and should be a singleton. services.AddSingleton<ModelBinding.IModelMetadataProvider, DefaultModelMetadataProvider>(); services.AddTransient<ModelBinding.Metadata.ICompositeMetadataDetailsProvider>(serviceProvider => { var options = serviceProvider.GetRequiredService<IOptions<MvcOptions>>().Options; return new DefaultCompositeMetadataDetailsProvider(options.ModelMetadataDetailsProviders); }); services.AddTransient<IInputFormatterSelector, DefaultInputFormatterSelector>(); services.AddScoped<IInputFormattersProvider, DefaultInputFormattersProvider>(); services.AddTransient<IModelBinderProvider, DefaultModelBindersProvider>(); services.AddTransient<IValueProviderFactoryProvider, DefaultValueProviderFactoryProvider>(); services.AddTransient<IOutputFormattersProvider, DefaultOutputFormattersProvider>(); services.AddInstance(new JsonOutputFormatter()); services.AddTransient<IModelValidatorProviderProvider, DefaultModelValidatorProviderProvider>(); services.AddTransient<IValidationExcludeFiltersProvider, DefaultValidationExcludeFiltersProvider>(); // Razor, Views and runtime compilation // The provider is inexpensive to initialize and provides ViewEngines that may require request // specific services. services.AddScoped<ICompositeViewEngine, CompositeViewEngine>(); services.AddTransient<IViewEngineProvider, DefaultViewEngineProvider>(); // Transient since the IViewLocationExpanders returned by the instance is cached by view engines. services.AddTransient<IViewLocationExpanderProvider, DefaultViewLocationExpanderProvider>(); // Caches view locations that are valid for the lifetime of the application. services.AddSingleton<IViewLocationCache, DefaultViewLocationCache>(); services.AddSingleton<ICodeTreeCache>(serviceProvider => { var cachedFileProvider = serviceProvider.GetRequiredService<IOptions<RazorViewEngineOptions>>(); return new DefaultCodeTreeCache(cachedFileProvider.Options.FileProvider); }); // The host is designed to be discarded after consumption and is very inexpensive to initialize. services.AddTransient<IMvcRazorHost, MvcRazorHost>(); // Caches compilation artifacts across the lifetime of the application. services.AddSingleton<ICompilerCache, CompilerCache>(); // This caches compilation related details that are valid across the lifetime of the application // and is required to be a singleton. services.AddSingleton<ICompilationService, RoslynCompilationService>(); // Both the compiler cache and roslyn compilation service hold on the compilation related // caches. RazorCompilation service is just an adapter service, and it is transient to ensure // the IMvcRazorHost dependency does not maintain state. services.AddTransient<IRazorCompilationService, RazorCompilationService>(); // The ViewStartProvider needs to be able to consume scoped instances of IRazorPageFactory services.AddScoped<IViewStartProvider, ViewStartProvider>(); services.AddTransient<IRazorViewFactory, RazorViewFactory>(); services.AddSingleton<IRazorPageActivator, RazorPageActivator>(); // Virtual path view factory needs to stay scoped so views can get get scoped services. services.AddScoped<IRazorPageFactory, VirtualPathRazorPageFactory>(); // View and rendering helpers services.AddTransient<IHtmlHelper, HtmlHelper>(); services.AddTransient(typeof(IHtmlHelper<>), typeof(HtmlHelper<>)); services.AddScoped<IUrlHelper, UrlHelper>(); // Only want one ITagHelperActivator so it can cache Type activation information. Types won't conflict. services.AddSingleton<ITagHelperActivator, DefaultTagHelperActivator>(); // Consumed by the Cache tag helper to cache results across the lifetime of the application. services.AddSingleton<IMemoryCache, MemoryCache>(); // DefaultHtmlGenerator is pretty much stateless but depends on Scoped services such as IUrlHelper and // IActionBindingContextProvider. Therefore it too is scoped. services.AddTransient<IHtmlGenerator, DefaultHtmlGenerator>(); // These do caching so they should stay singleton services.AddSingleton<IViewComponentSelector, DefaultViewComponentSelector>(); services.AddSingleton<IViewComponentActivator, DefaultViewComponentActivator>(); services.AddSingleton<IViewComponentDescriptorCollectionProvider, DefaultViewComponentDescriptorCollectionProvider>(); services.AddTransient<IViewComponentDescriptorProvider, DefaultViewComponentDescriptorProvider>(); services.AddTransient<IViewComponentInvokerFactory, DefaultViewComponentInvokerFactory>(); services.AddTransient<IViewComponentHelper, DefaultViewComponentHelper>(); // Security and Authorization services.AddSingleton<IClaimUidExtractor, DefaultClaimUidExtractor>(); services.AddSingleton<AntiForgery, AntiForgery>(); services.AddSingleton<IAntiForgeryAdditionalDataProvider, DefaultAntiForgeryAdditionalDataProvider>(); // Api Description services.AddSingleton<IApiDescriptionGroupCollectionProvider, ApiDescriptionGroupCollectionProvider>(); services.AddTransient<IApiDescriptionProvider, DefaultApiDescriptionProvider>(); // Temp Data services.AddSingleton<ITempDataProvider, SessionStateTempDataProvider>(); services.AddScoped<ITempDataDictionary, TempDataDictionary>(); return services; }