Orchard剖析開篇之依賴注入Autofac


在Orchard中大量使用Autofac依賴注入,所以講解Orchard之前,這個是必不可少的。

首先,我們先來看看Orchard.Web項目下的Glogal文件。

文件中,我們看到如下代碼:

 1 public class MvcApplication : HttpApplication {
 2         private static Starter<IOrchardHost> _starter;
 3 
 4         public MvcApplication() {
 5         }
 6 
 7         public static void RegisterRoutes(RouteCollection routes) {
 8             routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
 9         }
10 
11         protected void Application_Start() {
12             RegisterRoutes(RouteTable.Routes);
13             _starter = new Starter<IOrchardHost>(HostInitialization, HostBeginRequest, HostEndRequest);
14             _starter.OnApplicationStart(this);
15         }
16 
17         protected void Application_BeginRequest() {
18             _starter.OnBeginRequest(this);
19         }
20 
21         protected void Application_EndRequest() {
22             _starter.OnEndRequest(this);
23         }
24 
25         private static void HostBeginRequest(HttpApplication application, IOrchardHost host) {
26             application.Context.Items["originalHttpContext"] = application.Context;
27             host.BeginRequest();
28         }
29 
30         private static void HostEndRequest(HttpApplication application, IOrchardHost host) {
31             host.EndRequest();
32         }
33 
34         private static IOrchardHost HostInitialization(HttpApplication application) {
35             var host = OrchardStarter.CreateHost(MvcSingletons);
36 
37             host.Initialize();
38 
39             // initialize shells to speed up the first dynamic query
40             host.BeginRequest();
41             host.EndRequest();
42 
43             return host;
44         }
45 
46         static void MvcSingletons(ContainerBuilder builder) {
47             builder.Register(ctx => RouteTable.Routes).SingleInstance();
48             builder.Register(ctx => ModelBinders.Binders).SingleInstance();
49             builder.Register(ctx => ViewEngines.Engines).SingleInstance();
50         }
51     }

好了,現在我們來分析下這里面的代碼。

首先我們先看下Application_Start()函數,這個是站點的啟動入口

在這個函數里,我們可以看到函數里對一個靜態的Starter啟動器進行了初始化。

好了,接下里我們來看下Starter這個啟動器的構造函數。

從Starter的構造函數,我們可以發現構造函數聲明了三個委托,分別用於處理程序初始化,接收到請求以及請求處理結束時觸發的事件。

看到這里,我們也知道了這三個委托聲明的含義了。

那么,接下類。我們回到Application_Start()函數中來。

我們先看下HostInitialization委托的實現。

委托主要是實現了Orchard宿主的創建以及初始化工作。

細心的朋友可能已經發現了,Orchard宿主的實例工作是由一個靜態的OrchardStarter類的一個創建宿主的接口來執行的。

既然如此,我們就來看看這個接口到底做了哪些事。

觀察CreateHost接口,我們發現里面有一個CreateHostContainer的接口。它創建了一個容器IContainer對象,然后從容器中解析出宿主返回回去。

看到這里,我相信認真的朋友應該可以看出來了。作者在IContainer容器內注冊了IOrchardHost宿主的實現方式,所以客戶端可以通過這個容器去獲得IOrchardHost宿主。

可能也有的朋友到這里有疑惑,IContainer是個什么東西。

 那好,我這里給大家說明一下。

IContainer是Autofac提供的一個容器,這個容器由Autofac的構建者ContainerBuilder對象構建出來的。而ContainerBuilder有怎么知道實例怎么實現呢。

那么,接下來我們就來看下CreateHostContainer這個接口,看完后,相信大家就能豁然開然了。

  1  public static IContainer CreateHostContainer(Action<ContainerBuilder> registrations) {
  2             ExtensionLocations extensionLocations = new ExtensionLocations();
  3 
  4             var builder = new ContainerBuilder();
  5             // Application paths and parameters
  6             builder.RegisterInstance(extensionLocations);
  7 
  8             builder.RegisterModule(new CollectionOrderModule());
  9             builder.RegisterModule(new LoggingModule());
 10             builder.RegisterModule(new EventsModule());
 11             builder.RegisterModule(new CacheModule());
 12 
 13             // a single default host implementation is needed for bootstrapping a web app domain
 14             builder.RegisterType<DefaultOrchardEventBus>().As<IEventBus>().SingleInstance();
 15             builder.RegisterType<DefaultCacheHolder>().As<ICacheHolder>().SingleInstance();
 16             builder.RegisterType<DefaultCacheContextAccessor>().As<ICacheContextAccessor>().SingleInstance();
 17             builder.RegisterType<DefaultParallelCacheContext>().As<IParallelCacheContext>().SingleInstance();
 18             builder.RegisterType<DefaultAsyncTokenProvider>().As<IAsyncTokenProvider>().SingleInstance();
 19             builder.RegisterType<DefaultHostEnvironment>().As<IHostEnvironment>().SingleInstance();
 20             builder.RegisterType<DefaultHostLocalRestart>().As<IHostLocalRestart>().Named<IEventHandler>(typeof(IShellSettingsManagerEventHandler).Name).SingleInstance();
 21             builder.RegisterType<DefaultBuildManager>().As<IBuildManager>().SingleInstance();
 22             builder.RegisterType<DynamicModuleVirtualPathProvider>().As<ICustomVirtualPathProvider>().SingleInstance();
 23             builder.RegisterType<AppDataFolderRoot>().As<IAppDataFolderRoot>().SingleInstance();
 24             builder.RegisterType<DefaultExtensionCompiler>().As<IExtensionCompiler>().SingleInstance();
 25             builder.RegisterType<DefaultRazorCompilationEvents>().As<IRazorCompilationEvents>().SingleInstance();
 26             builder.RegisterType<DefaultProjectFileParser>().As<IProjectFileParser>().SingleInstance();
 27             builder.RegisterType<DefaultAssemblyLoader>().As<IAssemblyLoader>().SingleInstance();
 28             builder.RegisterType<AppDomainAssemblyNameResolver>().As<IAssemblyNameResolver>().SingleInstance();
 29             builder.RegisterType<GacAssemblyNameResolver>().As<IAssemblyNameResolver>().SingleInstance();
 30             builder.RegisterType<OrchardFrameworkAssemblyNameResolver>().As<IAssemblyNameResolver>().SingleInstance();
 31             builder.RegisterType<HttpContextAccessor>().As<IHttpContextAccessor>().InstancePerDependency();
 32             builder.RegisterType<ViewsBackgroundCompilation>().As<IViewsBackgroundCompilation>().SingleInstance();
 33             builder.RegisterType<DefaultExceptionPolicy>().As<IExceptionPolicy>().SingleInstance();
 34             builder.RegisterType<DefaultCriticalErrorProvider>().As<ICriticalErrorProvider>().SingleInstance();
 35             //builder.RegisterType<RazorTemplateCache>().As<IRazorTemplateProvider>().SingleInstance();
 36 
 37             RegisterVolatileProvider<WebSiteFolder, IWebSiteFolder>(builder);
 38             RegisterVolatileProvider<AppDataFolder, IAppDataFolder>(builder);
 39             RegisterVolatileProvider<DefaultLockFileManager, ILockFileManager>(builder);
 40             RegisterVolatileProvider<Clock, IClock>(builder);
 41             RegisterVolatileProvider<DefaultDependenciesFolder, IDependenciesFolder>(builder);
 42             RegisterVolatileProvider<DefaultExtensionDependenciesManager, IExtensionDependenciesManager>(builder);
 43             RegisterVolatileProvider<DefaultAssemblyProbingFolder, IAssemblyProbingFolder>(builder);
 44             RegisterVolatileProvider<DefaultVirtualPathMonitor, IVirtualPathMonitor>(builder);
 45             RegisterVolatileProvider<DefaultVirtualPathProvider, IVirtualPathProvider>(builder);
 46             
 47             builder.RegisterType<DefaultOrchardHost>().As<IOrchardHost>().As<IEventHandler>()
 48                 .Named<IEventHandler>(typeof(IShellSettingsManagerEventHandler).Name)
 49                 .Named<IEventHandler>(typeof(IShellDescriptorManagerEventHandler).Name)
 50                 .SingleInstance();
 51             {
 52                 builder.RegisterType<ShellSettingsManager>().As<IShellSettingsManager>().SingleInstance();
 53 
 54                 builder.RegisterType<ShellContextFactory>().As<IShellContextFactory>().SingleInstance();
 55                 {
 56                     builder.RegisterType<ShellDescriptorCache>().As<IShellDescriptorCache>().SingleInstance();
 57 
 58                     builder.RegisterType<CompositionStrategy>().As<ICompositionStrategy>().SingleInstance();
 59                     {
 60                         builder.RegisterType<ShellContainerRegistrations>().As<IShellContainerRegistrations>().SingleInstance();
 61                         builder.RegisterType<ExtensionLoaderCoordinator>().As<IExtensionLoaderCoordinator>().SingleInstance();
 62                         builder.RegisterType<ExtensionMonitoringCoordinator>().As<IExtensionMonitoringCoordinator>().SingleInstance();
 63                         builder.RegisterType<ExtensionManager>().As<IExtensionManager>().SingleInstance();
 64                         {
 65                             builder.RegisterType<ExtensionHarvester>().As<IExtensionHarvester>().SingleInstance();
 66                             builder.RegisterType<ModuleFolders>().As<IExtensionFolders>().SingleInstance()
 67                                 .WithParameter(new NamedParameter("paths", extensionLocations.ModuleLocations));
 68                             builder.RegisterType<CoreModuleFolders>().As<IExtensionFolders>().SingleInstance()
 69                                 .WithParameter(new NamedParameter("paths", extensionLocations.CoreLocations));
 70                             builder.RegisterType<ThemeFolders>().As<IExtensionFolders>().SingleInstance()
 71                                 .WithParameter(new NamedParameter("paths", extensionLocations.ThemeLocations));
 72 
 73                             builder.RegisterType<CoreExtensionLoader>().As<IExtensionLoader>().SingleInstance();
 74                             builder.RegisterType<ReferencedExtensionLoader>().As<IExtensionLoader>().SingleInstance();
 75                             builder.RegisterType<PrecompiledExtensionLoader>().As<IExtensionLoader>().SingleInstance();
 76                             builder.RegisterType<DynamicExtensionLoader>().As<IExtensionLoader>().SingleInstance();
 77                             builder.RegisterType<RawThemeExtensionLoader>().As<IExtensionLoader>().SingleInstance();
 78                         }
 79                     }
 80 
 81                     builder.RegisterType<ShellContainerFactory>().As<IShellContainerFactory>().SingleInstance();
 82                 }
 83 
 84                 builder.RegisterType<DefaultProcessingEngine>().As<IProcessingEngine>().SingleInstance();
 85             }
 86 
 87             builder.RegisterType<RunningShellTable>().As<IRunningShellTable>().SingleInstance();
 88             builder.RegisterType<DefaultOrchardShell>().As<IOrchardShell>().InstancePerMatchingLifetimeScope("shell");
 89             builder.RegisterType<SessionConfigurationCache>().As<ISessionConfigurationCache>().InstancePerMatchingLifetimeScope("shell");
 90 
 91             registrations(builder);
 92 
 93             var autofacSection = ConfigurationManager.GetSection(ConfigurationSettingsReaderConstants.DefaultSectionName);
 94             if (autofacSection != null)
 95                 builder.RegisterModule(new ConfigurationSettingsReader());
 96 
 97             var optionalHostConfig = HostingEnvironment.MapPath("~/Config/Host.config");
 98             if (File.Exists(optionalHostConfig))
 99                 builder.RegisterModule(new ConfigurationSettingsReader(ConfigurationSettingsReaderConstants.DefaultSectionName, optionalHostConfig));
100 
101             var optionalComponentsConfig = HostingEnvironment.MapPath("~/Config/HostComponents.config");
102             if (File.Exists(optionalComponentsConfig))
103                 builder.RegisterModule(new HostComponentsConfigModule(optionalComponentsConfig));
104 
105             var container = builder.Build();
106 
107             //
108             // Register Virtual Path Providers
109             //
110             if (HostingEnvironment.IsHosted) {
111                 foreach (var vpp in container.Resolve<IEnumerable<ICustomVirtualPathProvider>>()) {
112                     HostingEnvironment.RegisterVirtualPathProvider(vpp.Instance);
113                 }
114             }
115 
116             ControllerBuilder.Current.SetControllerFactory(new OrchardControllerFactory());
117             FilterProviders.Providers.Add(new OrchardFilterProvider());
118 
119             GlobalConfiguration.Configuration.Services.Replace(typeof(IHttpControllerSelector), new DefaultOrchardWebApiHttpControllerSelector(GlobalConfiguration.Configuration));
120             GlobalConfiguration.Configuration.Services.Replace(typeof(IHttpControllerActivator), new DefaultOrchardWebApiHttpControllerActivator(GlobalConfiguration.Configuration));
121             GlobalConfiguration.Configuration.DependencyResolver = new AutofacWebApiDependencyResolver(container);
122 
123             GlobalConfiguration.Configuration.Filters.Add(new OrchardApiActionFilterDispatcher());
124             GlobalConfiguration.Configuration.Filters.Add(new OrchardApiExceptionFilterDispatcher());
125             GlobalConfiguration.Configuration.Filters.Add(new OrchardApiAuthorizationFilterDispatcher());
126 
127             ViewEngines.Engines.Clear();
128             ViewEngines.Engines.Add(new ThemeAwareViewEngineShim());
129 
130             var hostContainer = new DefaultOrchardHostContainer(container);
131             //MvcServiceLocator.SetCurrent(hostContainer);
132             OrchardHostContainerRegistry.RegisterHostContainer(hostContainer);
133 
134             // Register localized data annotations
135             ModelValidatorProviders.Providers.Clear();
136             ModelValidatorProviders.Providers.Add(new LocalizedModelValidatorProvider());
137 
138             return container;
139         }

 這個接口代碼有點多,朋友們看起來應該有點累。所以我簡化一下大概代碼如下

 1  public static IContainer CreateHostContainer(Action<ContainerBuilder> registrations)
 2         {
 3             var builder = new ContainerBuilder();
 4             //to do register
 5 
 6             //builder.RegisterInstance()
 7 
 8             //builder.RegisterModule();
 9 
10             //builder.RegisterType<>().As<>().SingleInstance();
11 
12             //builder.RegisterType<>().As<>().InstancePerDependency();
13 
14             //to do register delegate Method
15             registrations(builder);
16 
17             var container = builder.Build();
18 
19             //to do register virtual path providers
20 
21 
22             return container;
23         }

通過觀察上面這段代碼,可以看出來。

這個接口就做了幾件事:

1.初始化IOC構建器ContainerBuilder

2.依賴注入注冊約定

3.構建容器IContainer

這個接口不過是做了很多關於IOC依賴注入的注冊工作。

 

Autofac在Orchard框架中扮演了一個很重要的角色,Autofac為Orchard框架提供了很高的擴展性。

相關的IOC依賴注入大家可以看下http://www.cnblogs.com/xrainchen/articles/5962993.html

好了,開篇介紹工作就講到這里。

 

下一篇:Orchard.Cache講解

 

如果你對我的文章有疑問,希望你可以在下方評論區留言。我會抽空為你解答。

如果你覺得我的文章還不錯,希望能分享出去。讓更多的朋友一起共同學習。你們的認可,是我分享的動力。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM