// TODO see if we can't get rid of this CompositionContainer public Template Load(CompositionContainer container) { Template ret = new Template(container); ret.Load(this); return ret; }
protected void Application_Start() { // TODO maybe put this somewhere else (not in global.asax) // TODO maybe move all of this into the App class with "IAppConfig" // initialize logger TraceListener traceListener = new TextWriterTraceListener(Path.Combine(AppConfig.LogPath, string.Format("repository_{0:yyyy'-'MM'-'dd__HHmmss}.log", DateTime.Now))); // TODO introduce flags/settings for controlling logging levels, but for now include everything traceListener.Filter = new EventTypeFilter(SourceLevels.All); traceListener.TraceOutputOptions = TraceOptions.ThreadId | TraceOptions.DateTime; Web.TraceSources.Content.Listeners.Add(traceListener); Web.TraceSources.AddInManager.Listeners.Add(traceListener); Repository.TraceSources.ContentManagerSource.Listeners.Add(traceListener); Repository.TraceSources.ContentSearcherSource.Listeners.Add(traceListener); // this might be stupid, but it fixes things for iisexpress Directory.SetCurrentDirectory(HostingEnvironment.ApplicationPhysicalPath); // set up add-in system AddInSource officalSource = new AddInSource("Official LostDoc repository add-in feed", AppConfig.AddInRepository, isOfficial: true); // intialize MEF // core 'add-ins' var currentAssembly = Assembly.GetExecutingAssembly(); var assemblyName = currentAssembly.GetName(); string corePackageId = assemblyName.Name; string corePackageVersion = assemblyName.Version.ToString(); AggregateCatalog catalog = new AggregateCatalog(); // load other sources from site-settings (not config) AddInRepository repository = new AddInRepository(officalSource); AddInManager addInManager = new AddInManager(repository, AppConfig.AddInInstallPath, AppConfig.AddInPackagePath); // when the catalog changes, discover and route all ApiControllers catalog.Changed += (sender, args) => this.UpdateWebApiRegistry(args); //// TODO for debugging only //Debugger.Break(); //Debugger.Launch(); // now register core libs catalog.Catalogs.Add(new AddInCatalog(new ApplicationCatalog(), corePackageId, corePackageVersion)); // hook event so that installed add-ins get registered in the catalog, if composition occurs after this fires // or if recomposition is enabled, no restart should be requried addInManager.Installed += (sender, args) => catalog.Catalogs.Add(new AddInCatalog(new DirectoryCatalog(args.InstallationPath), args.Package.Id, args.Package.Version)); // delete and redeploy all installed packages, this will trigger the Installed event ^ // this acts as a crude "remove/overwrite plugins that were in use when un/installed" hack addInManager.Restore(); // create container CompositionContainer container = new CompositionContainer(catalog); // set up template resolver var lazyProviders = container.GetExports<IFileProvider>(ContractNames.TemplateProvider); var realProviders = lazyProviders.Select(lazy => lazy.Value); TemplateResolver templateResolver = new TemplateResolver(realProviders.ToArray()); // load template Template template = new Template(container); template.Load(templateResolver, AppConfig.Template); // set up content manager ContentManager contentManager = new ContentManager(new ContentSettings { ContentPath = AppConfig.ContentPath, // TODO make this configurable IgnoreVersionComponent = VersionComponent.Patch, RepositoryPath = AppConfig.RepositoryPath, Template = template }); // set up notifaction system NotificationManager notifications = new NotificationManager(); // initialize app-singleton App.Initialize(container, contentManager, addInManager, notifications, traceListener); // MVC init AreaRegistration.RegisterAllAreas(); RegisterGlobalFilters(GlobalFilters.Filters); RegisterRoutes(RouteTable.Routes); // inject our custom IControllerFactory for the Admin interface IControllerFactory oldControllerFactory = ControllerBuilder.Current.GetControllerFactory(); IControllerFactory newControllerFactory = new AddInControllerFactory(AdministrationAreaRegistration.Name, container, oldControllerFactory); ControllerBuilder.Current.SetControllerFactory(newControllerFactory); // TODO figure out if we actually need this // hook in our MEF based IHttpController instead of the default one //GlobalConfiguration.Configuration.Services.Replace(typeof(IHttpControllerTypeResolver), new AddInHttpControllerTypeResolver(App.Instance.Container)); }
public void Invoke(CompositionContainer container) { var traceListener = new ConsolidatedConsoleTraceListener( new Dictionary<string, string> { { "LostDoc.Core.Template", "Template" }, { "LostDoc.Core.Bundle", "Bundle" }, { "LostDoc.Core.Template.AssetResolver", "Resolve" } }); TraceSources.TemplateSource.Listeners.Add(traceListener); TraceSources.AssetResolverSource.Listeners.Add(traceListener); try { if (this.Quiet.IsPresent) { const SourceLevels quietLevel = SourceLevels.Error | SourceLevels.Warning | SourceLevels.Critical; TraceSources.TemplateSource.Switch.Level = quietLevel; TraceSources.AssetResolverSource.Switch.Level = quietLevel; TraceSources.BundleSource.Listeners.Add(traceListener); } else if (this.Verbose.IsPresent) { const SourceLevels verboseLevel = SourceLevels.All; TraceSources.TemplateSource.Switch.Level = verboseLevel; TraceSources.AssetResolverSource.Switch.Level = verboseLevel; TraceSources.BundleSource.Listeners.Add(traceListener); } else { const SourceLevels normalLevel = SourceLevels.Information | SourceLevels.Warning | SourceLevels.Error | SourceLevels.ActivityTracing; TraceSources.TemplateSource.Switch.Level = normalLevel; TraceSources.AssetResolverSource.Switch.Level = normalLevel; } LinkedList<FileInfo> includedFiles = new LinkedList<FileInfo>(); if (File.Exists(this.Path)) includedFiles.AddLast(new FileInfo(this.Path)); else if (Directory.Exists(this.Path)) { Directory.GetFiles(this.Path, "*.ldoc", SearchOption.AllDirectories) .Aggregate(includedFiles, (l, f) => l.AddLast(new FileInfo(f)).List); } else throw new FileNotFoundException(System.IO.Path.GetFullPath(this.Path)); Bundle bundle = new Bundle(this.IgnoreVersionComponent); TraceSources.TemplateSource.TraceInformation("Merging LostDoc files into bundle."); foreach (FileInfo file in includedFiles) { TraceSources.TemplateSource.TraceEvent(TraceEventType.Information, 0, "Source: {0}", file.Name); XDocument fileDoc = XDocument.Load(file.FullName); bundle.Add(fileDoc); } var lazyProviders = container.GetExports<IFileProvider>(ContractNames.TemplateProvider); var realProviders = lazyProviders.Select(lazy => lazy.Value); TemplateResolver templateResolver = new TemplateResolver(realProviders.ToArray()); Template template = new Template(container); template.Load(templateResolver, this.Template); string outputDir = this.Output ?? (Directory.Exists(this.Path) ? this.Path : System.IO.Path.GetDirectoryName(this.Path)); AssetRedirectCollection assetRedirects; XDocument mergedDoc = bundle.Merge(out assetRedirects); var templateData = new TemplateData(mergedDoc) { AssetRedirects = assetRedirects, OverwriteExistingFiles = this.Force.IsPresent, IgnoredVersionComponent = this.IgnoreVersionComponent, Arguments = this.Arguments, OutputFileProvider = new ScopedFileProvider(new DirectoryFileProvider(), outputDir) }; template.Generate(templateData); } finally { TraceSources.TemplateSource.Listeners.Remove(traceListener); TraceSources.AssetResolverSource.Listeners.Remove(traceListener); } }
protected virtual ParsedTemplate PrepareTemplate(TemplateData templateData, Stack<IFileProvider> providers = null) { // set up temp file container TempFileCollection tempFiles = new TempFileCollection(templateData.TemporaryFilesPath, templateData.KeepTemporaryFiles); if (!Directory.Exists(tempFiles.TempDir)) Directory.CreateDirectory(tempFiles.TempDir); if (providers == null) providers = new Stack<IFileProvider>(); // clone orig doc XDocument workingDoc; // this is required to preserve the line information using (var xmlReader = this._templateDefinition.CreateReader()) workingDoc = XDocument.Load(xmlReader, LoadOptions.SetLineInfo); // template inheritence XAttribute templateInheritsAttr = workingDoc.Root.Attribute("inherits"); if (templateInheritsAttr != null) { int depth = providers.Count + 1; Template inheritedTemplate = new Template(this._container); inheritedTemplate.Load(this._templateResolver, templateInheritsAttr.Value); ParsedTemplate parsedTemplate = inheritedTemplate.PrepareTemplate(templateData, providers); providers.Push(inheritedTemplate.GetScopedFileProvider()); // a little hacky but it should work with the Reverse()/AddFirst() foreach (XElement elem in parsedTemplate.Source.Root.Elements().Reverse()) { workingDoc.Root.AddFirst(new XElement(elem)); } // create and register temp file (this can be overriden later if there are meta-template directives // in the template this._templateSourcePath = this.SaveTempFile(tempFiles, workingDoc, "inherited." + depth); } // add our file provider to the top of the stack providers.Push(this.GetScopedFileProvider()); // start by loading any parameters as they are needed for meta-template evaluation CustomXsltContext customContext = CreateCustomXsltContext(templateData.IgnoredVersionComponent); XElement[] paramNodes = workingDoc.Root.Elements("parameter").ToArray(); var globalParams = paramNodes.Select(paramNode => new ExpressionXPathVariable(this.GetAttributeValue(paramNode, "name"), this.GetAttributeValueOrDefault(paramNode, "select"))) .ToArray(); customContext.PushVariableScope(workingDoc, globalParams); var arguments = templateData.Arguments .Select(argument => new ConstantXPathVariable(argument.Key, argument.Value)) .ToArray(); customContext.PushVariableScope(workingDoc, arguments); // we're going to need this later XmlFileProviderResolver fileResolver = new XmlFileProviderResolver(providers, this._basePath); // expand any meta-template directives workingDoc = ApplyMetaTransforms(workingDoc, customContext, providers, tempFiles); // there was neither inheretance, nor any meta-template directives if (this._templateSourcePath == null) { // save current template to disk this._templateSourcePath = this.SaveTempFile(tempFiles, workingDoc); } // loading template List<Stylesheet> stylesheets = new List<Stylesheet>(); List<Resource> resources = new List<Resource>(); List<Index> indices = new List<Index>(); foreach (XElement elem in workingDoc.Root.Elements()) { // we alread proessed the parameters if (elem.Name.LocalName == "parameter") continue; if (elem.Name.LocalName == "apply-stylesheet") { stylesheets.Add(this.ParseStylesheet(providers, stylesheets, elem)); } else if (elem.Name.LocalName == "index") { indices.Add(this.ParseIndexDefinition(elem)); } else if (elem.Name.LocalName == "include-resource") { resources.Add(ParseResouceDefinition(providers, elem)); } else { throw new Exception("Unknown element: " + elem.Name.LocalName); } } return new ParsedTemplate { Parameters = globalParams, Source = workingDoc, Resources = resources.ToArray(), Stylesheets = stylesheets.ToArray(), Indices = indices.ToArray(), TemporaryFiles = tempFiles, }; }