Orchard代码学习笔记 -1. 入口

本文介绍了Orchard CMS中的依赖注入实现方式,包括不同作用域的依赖项定义方法及其实现原理。深入探讨了Orchard如何通过Autofac进行依赖注册与解析。

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/archive/2011/01/30/1947917.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值