public ILifetimeScope CreateContainer(ShellSettings settings, ShellBlueprint blueprint) { var intermediateScope = _lifetimeScope.BeginLifetimeScope( builder => { foreach (var item in blueprint.Dependencies.Where(t => typeof(IModule).IsAssignableFrom(t.Type))) { var registration = RegisterType(builder, item) .Keyed <IModule>(item.Type) .InstancePerDependency(); foreach (var parameter in item.Parameters) { registration = registration .WithParameter(parameter.Name, parameter.Value) .WithProperty(parameter.Name, parameter.Value); } } }); return(intermediateScope.BeginLifetimeScope( "shell", builder => { var dynamicProxyContext = new DynamicProxyContext(); builder.Register(ctx => dynamicProxyContext); builder.Register(ctx => settings); builder.Register(ctx => blueprint.Descriptor); builder.Register(ctx => blueprint); var concreteRegistrationNames = new ConcurrentDictionary <Type, ConcurrentBag <NamedRegistration> >(); var moduleIndex = intermediateScope.Resolve <IIndex <Type, IModule> >(); foreach (var item in blueprint.Dependencies.Where(t => typeof(IModule).IsAssignableFrom(t.Type))) { builder.RegisterModule(moduleIndex[item.Type]); } var itemsToBeRegistered = new ConcurrentQueue <ItemToBeRegistered>(); var decorators = new ConcurrentQueue <DecoratorRegistration>(); foreach (var item in blueprint.Dependencies.Where(t => typeof(IDependency).IsAssignableFrom(t.Type))) { // Determine if this service is an IEventHandler var isEventHandler = typeof(IEventHandler).IsAssignableFrom(item.Type); // Harvest any interfaces that this service decorates var decoratingTypes = item.Type.GetInterfaces() .Where(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(IDecorator <>)) .Select(t => t.GetGenericArguments().First()); var isDecorator = decoratingTypes != null && decoratingTypes.Any(); if (isDecorator && isEventHandler) { Logger.Error(string.Format("Type `{0}` is an IDecorator, but is also an IEventHandler. Decorating IEventHandlers is not currently supported. This decorator will not be registered.", item.Type.FullName)); continue; } if (isDecorator) { // If this service is a decorator, we need to determine which types it decorates foreach (var itemToBeRegistered in itemsToBeRegistered) { foreach (var interfaceType in decoratingTypes) { if (itemToBeRegistered.InterfaceTypes.Contains(interfaceType)) { if (itemToBeRegistered.DecoratedTypes == null) { itemToBeRegistered.DecoratedTypes = new List <Type>(); } // Add to the collection of interfaces that are decorated only if this interface type has not previously been added if (!itemToBeRegistered.DecoratedTypes.Contains(interfaceType)) { itemToBeRegistered.DecoratedTypes.Add(interfaceType); } } } } } itemsToBeRegistered.Enqueue(new ItemToBeRegistered { Item = item, InterfaceTypes = GetInterfacesFromBlueprint(item), DecoratingTypes = decoratingTypes, IsEventHandler = isEventHandler }); } foreach (var itemToBeRegistered in itemsToBeRegistered) { var registration = RegisterType(builder, itemToBeRegistered.Item) .AsSelf() .EnableDynamicProxy(dynamicProxyContext) .InstancePerLifetimeScope(); var registrationName = registration.ActivatorData.ImplementationType.FullName; registration.Named(registrationName, itemToBeRegistered.Item.Type); foreach (var interfaceType in itemToBeRegistered.InterfaceTypes) { registration = SetRegistrationScope(interfaceType, registration); var itemIsDecorator = itemToBeRegistered.IsDecorator(interfaceType); var itemIsDecorated = itemToBeRegistered.IsDecorated(interfaceType); if (!itemIsDecorated && !itemIsDecorator) { // This item is not decorated by another implementation of this interface type and is not a decorator. // It should be registered as the implementation of this interface. The ensures that Autofac will resolve only a single implementation should there be one or more decorators. registration = registration.As(interfaceType); } if (itemIsDecorator) { // This item decorates the interface currently being registered. // It needs to be added to the list of decorators so that is can be registered once all of the concrete implementations have been registered. decorators.Enqueue(new DecoratorRegistration(interfaceType, itemToBeRegistered, itemIsDecorated)); } else { // This item is not a decorator. // We need to add it to the list of concrete implementations. This allows us to know the names of the implementations that need to be decorated should a decorator for this interface exist. AddConcreteRegistrationName(registrationName, interfaceType, itemToBeRegistered.Item.Type, concreteRegistrationNames); } } if (itemToBeRegistered.IsEventHandler) { var interfaces = itemToBeRegistered.Item.Type.GetInterfaces(); foreach (var interfaceType in interfaces) { // register named instance for each interface, for efficient filtering inside event bus // IEventHandler derived classes only if (interfaceType.GetInterface(typeof(IEventHandler).Name) != null) { registration = registration.Named <IEventHandler>(interfaceType.Name); } } } foreach (var parameter in itemToBeRegistered.Item.Parameters) { registration = registration .WithParameter(parameter.Name, parameter.Value) .WithProperty(parameter.Name, parameter.Value); } } foreach (var decorator in decorators) { // We need to ensure that there is an implementation of this service that can be decorated if (!concreteRegistrationNames.ContainsKey(decorator.InterfaceType) || concreteRegistrationNames[decorator.InterfaceType] == null || !concreteRegistrationNames[decorator.InterfaceType].Any()) { var exception = new SystemFatalException(T("The only registered implementations of `{0}` are decorators. In order to avoid circular dependenices, there must be at least one implementation that is not marked with the `OrchardDecorator` attribute.", decorator.InterfaceType.FullName)); Logger.Fatal(exception, "Could not complete dependency registration as a circular dependency chain has been found."); throw exception; } var decoratorNames = new ConcurrentBag <NamedRegistration>(); // For every implementation that can be decorated foreach (var namedRegistration in concreteRegistrationNames[decorator.InterfaceType]) { var registration = RegisterType(builder, decorator.ItemToBeRegistered.Item) .AsSelf() .EnableDynamicProxy(dynamicProxyContext) .InstancePerLifetimeScope(); registration = SetRegistrationScope(decorator.InterfaceType, registration); // Create a unique name for the decorator var decoratorName = string.Format("{0}-{1}", namedRegistration.Name, decorator.ItemToBeRegistered.Item.Type.FullName); registration = registration.Named(decoratorName, decorator.ItemToBeRegistered.Item.Type); // Tell Autofac to resolve the decorated service with the implementation that has already been registered registration = registration.WithParameter( (p, c) => p.ParameterType == decorator.InterfaceType, (p, c) => c.ResolveNamed(namedRegistration.Name, namedRegistration.ImplementationType)); if (!decorator.IsDecorated) { // This is the last decorator in the stack, so register it as the implmentation of the interface that it is decorating registration = registration.As(decorator.InterfaceType); } decoratorNames.Add(new NamedRegistration(decoratorName, decorator.ItemToBeRegistered.Item.Type)); } // Update the collection of implmentation names that can be decorated to contain only the decorators (this allows us to stack decorators) concreteRegistrationNames[decorator.InterfaceType] = decoratorNames; } foreach (var item in blueprint.Controllers) { var serviceKeyName = (item.AreaName + "/" + item.ControllerName).ToLowerInvariant(); var serviceKeyType = item.Type; RegisterType(builder, item) .EnableDynamicProxy(dynamicProxyContext) .Keyed <IController>(serviceKeyName) .Keyed <IController>(serviceKeyType) .WithMetadata("ControllerType", item.Type) .InstancePerDependency(); } foreach (var item in blueprint.HttpControllers) { var serviceKeyName = (item.AreaName + "/" + item.ControllerName).ToLowerInvariant(); var serviceKeyType = item.Type; RegisterType(builder, item) .EnableDynamicProxy(dynamicProxyContext) .Keyed <IHttpController>(serviceKeyName) .Keyed <IHttpController>(serviceKeyType) .WithMetadata("ControllerType", item.Type) .InstancePerDependency(); } // Register code-only registrations specific to a shell _shellContainerRegistrations.Registrations(builder); var optionalShellByNameConfig = HostingEnvironment.MapPath("~/Config/Sites." + settings.Name + ".config"); if (File.Exists(optionalShellByNameConfig)) { builder.RegisterModule(ConfigurationSettingsReaderFactory.CreateConfigurationSettingsReader(optionalShellByNameConfig)); } else { var optionalShellConfig = HostingEnvironment.MapPath("~/Config/Sites.config"); if (File.Exists(optionalShellConfig)) { builder.RegisterModule(ConfigurationSettingsReaderFactory.CreateConfigurationSettingsReader(optionalShellConfig)); } } var optionalComponentsConfig = HostingEnvironment.MapPath("~/Config/HostComponents.config"); if (File.Exists(optionalComponentsConfig)) { builder.RegisterModule(new HostComponentsConfigModule(optionalComponentsConfig)); } })); }
public static IContainer CreateHostContainer(Action <ContainerBuilder> registrations) { ExtensionLocations extensionLocations = new ExtensionLocations(); var builder = new ContainerBuilder(); // Application paths and parameters builder.RegisterInstance(extensionLocations); builder.RegisterModule(new CollectionOrderModule()); builder.RegisterModule(new LoggingModule()); builder.RegisterModule(new EventsModule()); builder.RegisterModule(new CacheModule()); // a single default host implementation is needed for bootstrapping a web app domain builder.RegisterType <DefaultOrchardEventBus>().As <IEventBus>().SingleInstance(); builder.RegisterType <DefaultCacheHolder>().As <ICacheHolder>().SingleInstance(); builder.RegisterType <DefaultCacheContextAccessor>().As <ICacheContextAccessor>().SingleInstance(); builder.RegisterType <DefaultParallelCacheContext>().As <IParallelCacheContext>().SingleInstance(); builder.RegisterType <DefaultAsyncTokenProvider>().As <IAsyncTokenProvider>().SingleInstance(); builder.RegisterType <DefaultHostEnvironment>().As <IHostEnvironment>().SingleInstance(); builder.RegisterType <DefaultHostLocalRestart>().As <IHostLocalRestart>().Named <IEventHandler>(typeof(IShellSettingsManagerEventHandler).Name).SingleInstance(); builder.RegisterType <DefaultBuildManager>().As <IBuildManager>().SingleInstance(); builder.RegisterType <DynamicModuleVirtualPathProvider>().As <ICustomVirtualPathProvider>().SingleInstance(); builder.RegisterType <AppDataFolderRoot>().As <IAppDataFolderRoot>().SingleInstance(); builder.RegisterType <DefaultExtensionCompiler>().As <IExtensionCompiler>().SingleInstance(); builder.RegisterType <DefaultRazorCompilationEvents>().As <IRazorCompilationEvents>().SingleInstance(); builder.RegisterType <DefaultProjectFileParser>().As <IProjectFileParser>().SingleInstance(); builder.RegisterType <DefaultAssemblyLoader>().As <IAssemblyLoader>().SingleInstance(); builder.RegisterType <AppDomainAssemblyNameResolver>().As <IAssemblyNameResolver>().SingleInstance(); builder.RegisterType <GacAssemblyNameResolver>().As <IAssemblyNameResolver>().SingleInstance(); builder.RegisterType <SystemFrameworkAssemblyNameResolver>().As <IAssemblyNameResolver>().SingleInstance(); builder.RegisterType <HttpContextAccessor>().As <IHttpContextAccessor>().InstancePerDependency(); // builder.RegisterType<ViewsBackgroundCompilation>().As<IViewsBackgroundCompilation>().SingleInstance(); builder.RegisterType <DefaultExceptionPolicy>().As <IExceptionPolicy>().SingleInstance(); builder.RegisterType <DefaultCriticalErrorProvider>().As <ICriticalErrorProvider>().SingleInstance(); builder.RegisterType <ResourceFileHashProvider>().As <IResourceFileHashProvider>().SingleInstance(); //builder.RegisterType<RazorTemplateCache>().As<IRazorTemplateProvider>().SingleInstance(); RegisterVolatileProvider <WebSiteFolder, IWebSiteFolder>(builder); RegisterVolatileProvider <AppDataFolder, IAppDataFolder>(builder); RegisterVolatileProvider <DefaultLockFileManager, ILockFileManager>(builder); RegisterVolatileProvider <Clock, IClock>(builder); RegisterVolatileProvider <DefaultDependenciesFolder, IDependenciesFolder>(builder); RegisterVolatileProvider <DefaultExtensionDependenciesManager, IExtensionDependenciesManager>(builder); RegisterVolatileProvider <DefaultAssemblyProbingFolder, IAssemblyProbingFolder>(builder); RegisterVolatileProvider <DefaultVirtualPathMonitor, IVirtualPathMonitor>(builder); RegisterVolatileProvider <DefaultVirtualPathProvider, IVirtualPathProvider>(builder); builder.RegisterType <DefaultSystemHost>().As <ISystemHost>().As <IEventHandler>() .Named <IEventHandler>(typeof(IShellSettingsManagerEventHandler).Name) .Named <IEventHandler>(typeof(IShellDescriptorManagerEventHandler).Name) .SingleInstance(); { builder.RegisterType <ShellSettingsManager>().As <IShellSettingsManager>().SingleInstance(); builder.RegisterType <ShellContextFactory>().As <IShellContextFactory>().SingleInstance(); { builder.RegisterType <ShellDescriptorCache>().As <IShellDescriptorCache>().SingleInstance(); builder.RegisterType <CompositionStrategy>().As <ICompositionStrategy>().SingleInstance(); { builder.RegisterType <ShellContainerRegistrations>().As <IShellContainerRegistrations>().SingleInstance(); builder.RegisterType <ExtensionLoaderCoordinator>().As <IExtensionLoaderCoordinator>().SingleInstance(); builder.RegisterType <ExtensionMonitoringCoordinator>().As <IExtensionMonitoringCoordinator>().SingleInstance(); builder.RegisterType <ExtensionManager>().As <IExtensionManager>().SingleInstance(); { builder.RegisterType <ExtensionHarvester>().As <IExtensionHarvester>().SingleInstance(); builder.RegisterType <ModuleFolders>().As <IExtensionFolders>().SingleInstance() .WithParameter(new NamedParameter("paths", extensionLocations.ModuleLocations)); builder.RegisterType <CoreModuleFolders>().As <IExtensionFolders>().SingleInstance() .WithParameter(new NamedParameter("paths", extensionLocations.CoreLocations)); builder.RegisterType <ThemeFolders>().As <IExtensionFolders>().SingleInstance() .WithParameter(new NamedParameter("paths", extensionLocations.ThemeLocations)); builder.RegisterType <CoreExtensionLoader>().As <IExtensionLoader>().SingleInstance(); builder.RegisterType <ReferencedExtensionLoader>().As <IExtensionLoader>().SingleInstance(); builder.RegisterType <PrecompiledExtensionLoader>().As <IExtensionLoader>().SingleInstance(); builder.RegisterType <DynamicExtensionLoader>().As <IExtensionLoader>().SingleInstance(); builder.RegisterType <RawThemeExtensionLoader>().As <IExtensionLoader>().SingleInstance(); } } builder.RegisterType <ShellContainerFactory>().As <IShellContainerFactory>().SingleInstance(); } // builder.RegisterType <DefaultProcessingEngine>().As <IProcessingEngine>().SingleInstance(); } builder.RegisterType <RunningShellTable>().As <IRunningShellTable>().SingleInstance(); builder.RegisterType <DefaultSystemShell>().As <ISystemShell>().InstancePerMatchingLifetimeScope("shell"); // builder.RegisterType<SessionConfigurationCache>().As<ISessionConfigurationCache>().InstancePerMatchingLifetimeScope("shell"); registrations(builder); var autofacSection = ConfigurationManager.GetSection(ConfigurationSettingsReaderConstants.DefaultSectionName); if (autofacSection != null) { // builder.RegisterModule(new ConfigurationSettingsReader()); builder.RegisterModule(ConfigurationSettingsReaderFactory.CreateConfigurationSettingsReader()); } var optionalHostConfig = HostingEnvironment.MapPath("~/Config/Host.config"); if (File.Exists(optionalHostConfig)) { // builder.RegisterModule(new ConfigurationSettingsReader(ConfigurationSettingsReaderConstants.DefaultSectionName, optionalHostConfig)); builder.RegisterModule(ConfigurationSettingsReaderFactory.CreateConfigurationSettingsReader(optionalHostConfig)); } var optionalComponentsConfig = HostingEnvironment.MapPath("~/Config/HostComponents.config"); if (File.Exists(optionalComponentsConfig)) { builder.RegisterModule(new HostComponentsConfigModule(optionalComponentsConfig)); } var container = builder.Build(); // // Register Virtual Path Providers // if (HostingEnvironment.IsHosted) { foreach (var vpp in container.Resolve <IEnumerable <ICustomVirtualPathProvider> >()) { HostingEnvironment.RegisterVirtualPathProvider(vpp.Instance); } } // ControllerBuilder.Current.SetControllerFactory(new SystemControllerFactory()); FilterProviders.Providers.Add(new SystemFilterProvider()); // GlobalConfiguration.Configuration.Services.Replace(typeof(IHttpControllerSelector), new DefaultSystemWebApiHttpControllerSelector(GlobalConfiguration.Configuration)); GlobalConfiguration.Configuration.Services.Replace(typeof(System.Web.Http.Dispatcher.IHttpControllerActivator), new DefaultSystemWebApiHttpControllerActivator(GlobalConfiguration.Configuration)); GlobalConfiguration.Configuration.DependencyResolver = new AutofacWebApiDependencyResolver(container); // GlobalConfiguration.Configuration.Filters.Add(new SystemApiActionFilterDispatcher()); GlobalConfiguration.Configuration.Filters.Add(new SystemApiExceptionFilterDispatcher()); GlobalConfiguration.Configuration.Filters.Add(new SystemApiAuthorizationFilterDispatcher()); ViewEngines.Engines.Clear(); ViewEngines.Engines.Add(new ThemeAwareViewEngineShim()); // var hostContainer = new DefaultSystemHostContainer(container); //MvcServiceLocator.SetCurrent(hostContainer); SystemHostContainerRegistry.RegisterHostContainer(hostContainer); // // // Register localized data annotations ModelValidatorProviders.Providers.Clear(); ModelValidatorProviders.Providers.Add(new LocalizedModelValidatorProvider()); return(container); }