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));
                }
            }));
        }
Esempio n. 2
0
        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);
        }