Orchard代码学习笔记 1. 入口

1.Orchard.Web.MvcApplication,Orchard.Web

protected void Application_Start() {
    RegisterRoutes(RouteTable.Routes);

    _host 
= OrchardStarter.CreateHost(MvcSingletons);
    _host.Initialize();
}

2.Orchard.Environment.OrchardStarter,Orchard.Framework

using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Web.Hosting;
using System.Web.Mvc;
using Autofac;
using Autofac.Configuration;
using Orchard.Caching;
using Orchard.Environment.Configuration;
using Orchard.Environment.Extensions;
using Orchard.Environment.Extensions.Compilers;
using Orchard.Environment.Extensions.Folders;
using Orchard.Environment.Extensions.Loaders;
using Orchard.Environment.ShellBuilders;
using Orchard.Environment.State;
using Orchard.Environment.Descriptor;
using Orchard.Events;
using Orchard.FileSystems.AppData;
using Orchard.FileSystems.Dependencies;
using Orchard.FileSystems.VirtualPath;
using Orchard.FileSystems.WebSite;
using Orchard.Logging;
using Orchard.Mvc;
using Orchard.Mvc.ViewEngines.Razor;
using Orchard.Mvc.ViewEngines.ThemeAwareness;
using Orchard.Services;

namespace Orchard.Environment {
    
public static class OrchardStarter {
        
public static IContainer CreateHostContainer(Action<ContainerBuilder> registrations) {
            var builder 
= new ContainerBuilder();
            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
<DefaultHostEnvironment>().As<IHostEnvironment>().SingleInstance();
            builder.RegisterType
<DefaultHostLocalRestart>().As<IHostLocalRestart>().SingleInstance();
            builder.RegisterType
<DefaultBuildManager>().As<IBuildManager>().SingleInstance();
            builder.RegisterType
<WebFormVirtualPathProvider>().As<ICustomVirtualPathProvider>().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
<OrchardFrameworkAssemblyNameResolver>().As<IAssemblyNameResolver>().SingleInstance();
            builder.RegisterType
<HttpContextAccessor>().As<IHttpContextAccessor>().SingleInstance();
            builder.RegisterType
<ViewsBackgroundCompilation>().As<IViewsBackgroundCompilation>().SingleInstance();

            RegisterVolatileProvider
<WebSiteFolder, IWebSiteFolder>(builder);
            RegisterVolatileProvider
<AppDataFolder, IAppDataFolder>(builder);
            RegisterVolatileProvider
<Clock, IClock>(builder);
            RegisterVolatileProvider
<DefaultDependenciesFolder, IDependenciesFolder>(builder);
            RegisterVolatileProvider
<DefaultAssemblyProbingFolder, IAssemblyProbingFolder>(builder);
            RegisterVolatileProvider
<DefaultVirtualPathMonitor, IVirtualPathMonitor>(builder);
            RegisterVolatileProvider
<DefaultVirtualPathProvider, IVirtualPathProvider>(builder);

            builder.RegisterType
<DefaultOrchardHost>().As<IOrchardHost>().As<IEventHandler>().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
<ExtensionManager>().As<IExtensionManager>().SingleInstance();
                        {
                            builder.RegisterType
<ModuleFolders>().As<IExtensionFolders>().SingleInstance()
                                .WithParameter(
new NamedParameter("paths"new[] { "~/Core""~/Modules" }));
                            builder.RegisterType
<ThemeFolders>().As<IExtensionFolders>().SingleInstance()
                                .WithParameter(
new NamedParameter("paths"new[] { "~/Core""~/Themes" }));

                            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
<DefaultOrchardShell>().As<IOrchardShell>().InstancePerMatchingLifetimeScope("shell");

            registrations(builder);


            var autofacSection 
= ConfigurationManager.GetSection(ConfigurationSettingsReader.DefaultSectionName);
            
if (autofacSection != null)
                builder.RegisterModule(
new ConfigurationSettingsReader());

            var optionalHostConfig 
= HostingEnvironment.MapPath("~/Config/Host.config");
            
if (File.Exists(optionalHostConfig))
                builder.RegisterModule(
new ConfigurationSettingsReader(ConfigurationSettingsReader.DefaultSectionName, 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 OrchardControllerFactory());
            ViewEngines.Engines.Clear();
            ViewEngines.Engines.Add(
new ThemeAwareViewEngineShim());

            var hostContainer 
= new DefaultOrchardHostContainer(container);
            
//MvcServiceLocator.SetCurrent(hostContainer);
            OrchardHostContainerRegistry.RegisterHostContainer(hostContainer);

            
return container;
        }


        
private static void RegisterVolatileProvider<TRegister, TService>(ContainerBuilder builder) where TService : IVolatileProvider {
            builder.RegisterType
<TRegister>()
                .As
<TService>()
                .As
<IVolatileProvider>()
                .SingleInstance();
        }

        
public static IOrchardHost CreateHost(Action<ContainerBuilder> registrations) {
            var container 
= CreateHostContainer(registrations);
            
return container.Resolve<IOrchardHost>();
        }
    }
}

3.Orchard.Environment.ShellBuilders.ShellContainerFactory,Orchard.Framework

using System;
using System.IO;
using System.Linq;
using System.Web.Hosting;
using System.Web.Mvc;
using Autofac;
using Autofac.Builder;
using Autofac.Configuration;
using Autofac.Core;
using Autofac.Features.Indexed;
using Orchard.Environment.AutofacUtil.DynamicProxy2;
using Orchard.Environment.Configuration;
using Orchard.Environment.ShellBuilders.Models;
using Orchard.Events;

namespace Orchard.Environment.ShellBuilders {

    
public interface IShellContainerFactory {
        ILifetimeScope CreateContainer(ShellSettings settings, ShellBlueprint blueprint);
    }

    
public class ShellContainerFactory : IShellContainerFactory {
        
private readonly ILifetimeScope _lifetimeScope;
        
private readonly IShellContainerRegistrations _shellContainerRegistrations;

        
public ShellContainerFactory(ILifetimeScope lifetimeScope, IShellContainerRegistrations shellContainerRegistrations) {
            _lifetimeScope 
= lifetimeScope;
            _shellContainerRegistrations 
= shellContainerRegistrations;
        }

        
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 moduleIndex 
= intermediateScope.Resolve<IIndex<Type, IModule>>();
                    
foreach (var item in blueprint.Dependencies.Where(t => typeof(IModule).IsAssignableFrom(t.Type))) {
                        builder.RegisterModule(moduleIndex[item.Type]);
                    }

                    
foreach (var item in blueprint.Dependencies.Where(t => typeof(IDependency).IsAssignableFrom(t.Type))) {
                        var registration 
= RegisterType(builder, item)
                            .EnableDynamicProxy(dynamicProxyContext)
                            .InstancePerLifetimeScope();

                        
foreach (var interfaceType in item.Type.GetInterfaces()
                            .Where(itf 
=> typeof(IDependency).IsAssignableFrom(itf) 
                                      
&& !typeof(IEventHandler).IsAssignableFrom(itf))) {
                            registration 
= registration.As(interfaceType);
                            
if (typeof(ISingletonDependency).IsAssignableFrom(interfaceType)) {
                                registration 
= registration.InstancePerMatchingLifetimeScope("shell");
                            } 
                            
else if (typeof(IUnitOfWorkDependency).IsAssignableFrom(interfaceType)) {
                                registration 
= registration.InstancePerMatchingLifetimeScope("work");
                            }
                            
else if (typeof(ITransientDependency).IsAssignableFrom(interfaceType)) {
                                registration 
= registration.InstancePerDependency();
                            }
                        }

                        
if (typeof(IEventHandler).IsAssignableFrom(item.Type)) {
                            registration 
= registration.As(typeof(IEventHandler));
                        }

                        
foreach (var parameter in item.Parameters) {
                            registration 
= registration
                                .WithParameter(parameter.Name, parameter.Value)
                                .WithProperty(parameter.Name, parameter.Value);
                        }
                    }

                    
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()
                            .OnActivating(e 
=> {
                                              var controller 
= e.Instance as Controller;
                                              
if (controller != null)
                                                  controller.ActionInvoker 
= (IActionInvoker)e.Context.Resolve(new TypedService(typeof(IActionInvoker)));
                                          });
                    }

                    
// Register code-only registrations specific to a shell
                    _shellContainerRegistrations.Registrations(builder);

                    var optionalShellConfig 
= HostingEnvironment.MapPath("~/Config/Sites.config");
                    
if (File.Exists(optionalShellConfig))
                        builder.RegisterModule(
new ConfigurationSettingsReader(ConfigurationSettingsReader.DefaultSectionName, optionalShellConfig));

                    var optionalShellByNameConfig 
= HostingEnvironment.MapPath("~/Config/Sites." + settings.Name + ".config");
                    
if (File.Exists(optionalShellByNameConfig))
                        builder.RegisterModule(
new ConfigurationSettingsReader(ConfigurationSettingsReader.DefaultSectionName, optionalShellByNameConfig));
                });
        }

        
private IRegistrationBuilder<object, ConcreteReflectionActivatorData, SingleRegistrationStyle> RegisterType(ContainerBuilder builder, ShellBlueprintItem item) {
            
return builder.RegisterType(item.Type)
                .WithProperty(
"Feature", item.Feature)
                .WithMetadata(
"Feature", item.Feature);
        }
    }
}

4.来自Orchard官方网站Documentation中的说明

Dependency injection

The standard way of creating injectable dependencies in Orchard is to create an interface that derives from IDependency or one of its derived interfaces and then to implement that interface. On the consuming side, you can take a parameter of the interface type in your constructor. The application framework will discover all dependencies and will take care of instantiating and injecting instances as needed.

There are three different possible scopes for dependencies, and choosing one is done by deriving from the right interface:

  • Request: a dependency instance is created for each new HTTP request and is destroyed once the request has been processed. Use this by deriving your interface from IDependency. The object should be reasonably cheap to create.
  • Object: a new instance is created every single time an object takes a dependency on the interface. Instances are never shared. Use this by deriving from ITransientDependency. The objects must be extremely cheap to create.
  • Shell: only one instance is created per shell/tenant. Use this by deriving from ISingletonDependency. Only use this for objects that must maintain a common state for the lifetime of the shell.

原文地址:https://www.cnblogs.com/llcto/p/1947917.html