public void OnApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext) { //If this flag exists and it's not 'true' then this container will be disabled. if (ConfigurationManager.AppSettings["Our.Umbraco.IoC.Autofac.Enabled"] != null && ConfigurationManager.AppSettings["Our.Umbraco.IoC.Autofac.Enabled"] != "true") { return; } var builder = new ContainerBuilder(); //register ASP.NET System types builder.RegisterModule <AutofacWebTypesModule>(); //register umbraco types builder.RegisterSource(new AutofacUmbracoRegister(UmbracoServices.GetAllRegistrations())); //register umbraco MVC + webapi controllers used by the admin site builder.RegisterControllers(typeof(UmbracoApplication).Assembly); builder.RegisterApiControllers(typeof(UmbracoApplication).Assembly); //Raise event so people can modify the container OnContainerBuilding(new ContainerBuildingEventArgs(builder, applicationContext, umbracoApplication)); var container = builder.Build(); //set dependency resolvers for both webapi and mvc DependencyResolver.SetResolver(new AutofacDependencyResolver(container)); GlobalConfiguration.Configuration.DependencyResolver = new AutofacWebApiDependencyResolver(container); }
public void ThrowsOnDuplicateAliases() { var typeModels = new List <TypeModel> { new() { ItemType = TypeModel.ItemTypes.Content, Alias = "content1" }, new() { ItemType = TypeModel.ItemTypes.Content, Alias = "content2" }, new() { ItemType = TypeModel.ItemTypes.Media, Alias = "media1" }, new() { ItemType = TypeModel.ItemTypes.Media, Alias = "media2" }, new() { ItemType = TypeModel.ItemTypes.Member, Alias = "member1" }, new() { ItemType = TypeModel.ItemTypes.Member, Alias = "member2" }, }; Assert.AreEqual(6, UmbracoServices.EnsureDistinctAliases(typeModels).Count); typeModels.Add(new TypeModel { ItemType = TypeModel.ItemTypes.Media, Alias = "content1" }); try { UmbracoServices.EnsureDistinctAliases(typeModels); } catch (NotSupportedException e) { Console.WriteLine(e.Message); return; } Assert.Fail("Expected NotSupportedException."); }
public void OnApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext) { //If this flag exists and it's not 'true' then this container will be disabled. if (ConfigurationManager.AppSettings["Our.Umbraco.IoC.Unity.Enabled"] != null && ConfigurationManager.AppSettings["Our.Umbraco.IoC.Unity.Enabled"] != "true") { return; } var container = new UnityContainer(); //register for shutdown HostingEnvironment.RegisterObject(new UnityShutdown(container)); //register ASP.NET System types container.RegisterWebTypes(); //register umbraco types var umbracoRegistrations = new UnityUmbracoRegister(container, UmbracoServices.GetAllRegistrations()); umbracoRegistrations.RegisterTypes(); //it is NOT necessary to register your controllers for Unity! //see https://code.msdn.microsoft.com/Dependency-Injection-in-11d54863 //Raise event so people can modify the container OnContainerBuilding(new ContainerBuildingEventArgs(container, applicationContext, umbracoApplication)); //set dependency resolvers for both webapi and mvc GlobalConfiguration.Configuration.DependencyResolver = new global::Unity.AspNet.WebApi.UnityDependencyResolver(container); DependencyResolver.SetResolver(new global::Unity.AspNet.Mvc.UnityDependencyResolver(container)); //custom MVC requirements for unity FilterProviders.Providers.Remove(FilterProviders.Providers.OfType <FilterAttributeFilterProvider>().First()); FilterProviders.Providers.Add(new UnityFilterAttributeFilterProvider(container)); }
public ModelsGenerator(UmbracoServices umbracoService, IOptions <ModelsBuilderSettings> config, OutOfDateModelsStatus outOfDateModels, IHostingEnvironment hostingEnvironment) { _umbracoService = umbracoService; _config = config.Value; _outOfDateModels = outOfDateModels; _hostingEnvironment = hostingEnvironment; }
public ModelsGenerator(UmbracoServices umbracoService, IOptionsMonitor <ModelsBuilderSettings> config, OutOfDateModelsStatus outOfDateModels, IHostingEnvironment hostingEnvironment) { _umbracoService = umbracoService; _config = config.CurrentValue; _outOfDateModels = outOfDateModels; _hostingEnvironment = hostingEnvironment; config.OnChange(x => _config = x); }
/// <summary> /// Used to check if a template is being created based on a document type, in this case we need to /// ensure the template markup is correct based on the model name of the document type /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void FileService_SavingTemplate(IFileService sender, Core.Events.SaveEventArgs <Core.Models.ITemplate> e) { // don't do anything if the factory is not enabled // because, no factory = no models (even if generation is enabled) if (!_config.EnableFactory) { return; } // don't do anything if this special key is not found if (!e.AdditionalData.ContainsKey("CreateTemplateForContentType")) { return; } // ensure we have the content type alias if (!e.AdditionalData.ContainsKey("ContentTypeAlias")) { throw new InvalidOperationException("The additionalData key: ContentTypeAlias was not found"); } foreach (var template in e.SavedEntities) { // if it is in fact a new entity (not been saved yet) and the "CreateTemplateForContentType" key // is found, then it means a new template is being created based on the creation of a document type if (!template.HasIdentity && string.IsNullOrWhiteSpace(template.Content)) { // ensure is safe and always pascal cased, per razor standard // + this is how we get the default model name in Umbraco.ModelsBuilder.Umbraco.Application var alias = e.AdditionalData["ContentTypeAlias"].ToString(); var name = template.Name; // will be the name of the content type since we are creating var className = UmbracoServices.GetClrName(name, alias); var modelNamespace = _config.ModelsNamespace; // we do not support configuring this at the moment, so just let Umbraco use its default value //var modelNamespaceAlias = ...; var markup = ViewHelper.GetDefaultFileContent( modelClassName: className, modelNamespace: modelNamespace /*, * modelNamespaceAlias: modelNamespaceAlias*/); //set the template content to the new markup template.Content = markup; } } }
public static Dictionary <string, string> GetModels(UmbracoServices umbracoServices, string modelsNamespace, IDictionary <string, string> files) { var typeModels = umbracoServices.GetAllTypes(); var parseResult = new CodeParser().ParseWithReferencedAssemblies(files); var builder = new TextBuilder(typeModels, parseResult, modelsNamespace); var models = new Dictionary <string, string>(); foreach (var typeModel in builder.GetModelsToGenerate()) { var sb = new StringBuilder(); builder.Generate(sb, typeModel); models[typeModel.ClrName] = sb.ToString(); } return(models); }
/// <summary> /// Used to check if a template is being created based on a document type, in this case we need to /// ensure the template markup is correct based on the model name of the document type /// </summary> public void Handle(TemplateSavingNotification notification) { if (_config.ModelsMode == ModelsMode.Nothing) { return; } // Don't do anything if we're not requested to create a template for a content type if (notification.CreateTemplateForContentType is false) { return; } // ensure we have the content type alias if (notification.ContentTypeAlias is null) { throw new InvalidOperationException("ContentTypeAlias was not found on the notification"); } foreach (ITemplate template in notification.SavedEntities) { // if it is in fact a new entity (not been saved yet) and the "CreateTemplateForContentType" key // is found, then it means a new template is being created based on the creation of a document type if (!template.HasIdentity && string.IsNullOrWhiteSpace(template.Content)) { // ensure is safe and always pascal cased, per razor standard // + this is how we get the default model name in Umbraco.ModelsBuilder.Umbraco.Application var alias = notification.ContentTypeAlias; var name = template.Name; // will be the name of the content type since we are creating var className = UmbracoServices.GetClrName(_shortStringHelper, name, alias); var modelNamespace = _config.ModelsNamespace; // we do not support configuring this at the moment, so just let Umbraco use its default value // var modelNamespaceAlias = ...; var markup = _defaultViewContentProvider.GetDefaultFileContent( modelClassName: className, modelNamespace: modelNamespace /*, * modelNamespaceAlias: modelNamespaceAlias*/); // set the template content to the new markup template.Content = markup; } } }
public ModelsGenerator(UmbracoServices umbracoService, IModelsBuilderConfig config, OutOfDateModelsStatus outOfDateModels) { _umbracoService = umbracoService; _config = config; _outOfDateModels = outOfDateModels; }
// This is NOT thread safe but it is only called from within a lock private Assembly GetModelsAssembly(bool forceRebuild) { if (!Directory.Exists(_pureLiveDirectory.Value)) { Directory.CreateDirectory(_pureLiveDirectory.Value); } IList <TypeModel> typeModels = UmbracoServices.GetAllTypes(); var currentHash = TypeModelHasher.Hash(typeModels); var modelsHashFile = Path.Combine(_pureLiveDirectory.Value, "models.hash"); var modelsSrcFile = Path.Combine(_pureLiveDirectory.Value, "models.generated.cs"); var projFile = Path.Combine(_pureLiveDirectory.Value, "all.generated.cs"); var dllPathFile = Path.Combine(_pureLiveDirectory.Value, "all.dll.path"); // caching the generated models speeds up booting // currentHash hashes both the types & the user's partials if (!forceRebuild) { _logger.LogDebug("Looking for cached models."); if (File.Exists(modelsHashFile) && File.Exists(projFile)) { var cachedHash = File.ReadAllText(modelsHashFile); if (currentHash != cachedHash) { _logger.LogDebug("Found obsolete cached models."); forceRebuild = true; } // else cachedHash matches currentHash, we can try to load an existing dll } else { _logger.LogDebug("Could not find cached models."); forceRebuild = true; } } Assembly assembly; if (!forceRebuild) { // try to load the dll directly (avoid rebuilding) // // ensure that the .dll file does not have a corresponding .dll.delete file // as that would mean the the .dll file is going to be deleted and should not // be re-used - that should not happen in theory, but better be safe if (File.Exists(dllPathFile)) { var dllPath = File.ReadAllText(dllPathFile); _logger.LogDebug($"Cached models dll at {dllPath}."); if (File.Exists(dllPath) && !File.Exists(dllPath + ".delete")) { assembly = ReloadAssembly(dllPath); ModelsBuilderAssemblyAttribute attr = assembly.GetCustomAttribute <ModelsBuilderAssemblyAttribute>(); if (attr != null && attr.IsInMemory && attr.SourceHash == currentHash) { // if we were to resume at that revision, then _ver would keep increasing // and that is probably a bad idea - so, we'll always rebuild starting at // ver 1, but we remember we want to skip that one - so we never end up // with the "same but different" version of the assembly in memory _skipver = assembly.GetName().Version.Revision; _logger.LogDebug("Loading cached models (dll)."); return(assembly); } _logger.LogDebug("Cached models dll cannot be loaded (invalid assembly)."); } else if (!File.Exists(dllPath)) { _logger.LogDebug("Cached models dll does not exist."); } else if (File.Exists(dllPath + ".delete")) { _logger.LogDebug("Cached models dll is marked for deletion."); } else { _logger.LogDebug("Cached models dll cannot be loaded (why?)."); } } // must reset the version in the file else it would keep growing // loading cached modules only happens when the app restarts var text = File.ReadAllText(projFile); Match match = s_assemblyVersionRegex.Match(text); if (match.Success) { text = text.Replace(match.Value, "AssemblyVersion(\"0.0.0." + _ver + "\")"); File.WriteAllText(projFile, text); } _ver++; try { var assemblyPath = GetOutputAssemblyPath(currentHash); RoslynCompiler.CompileToFile(projFile, assemblyPath); assembly = ReloadAssembly(assemblyPath); File.WriteAllText(dllPathFile, assembly.Location); File.WriteAllText(modelsHashFile, currentHash); TryDeleteUnusedAssemblies(dllPathFile); } catch { ClearOnFailingToCompile(dllPathFile, modelsHashFile, projFile); throw; } _logger.LogDebug("Loading cached models (source)."); return(assembly); } // need to rebuild _logger.LogDebug("Rebuilding models."); // generate code, save var code = GenerateModelsCode(typeModels); // add extra attributes, // IsLive=true helps identifying Assemblies that contain live models // AssemblyVersion is so that we have a different version for each rebuild var ver = _ver == _skipver ? ++_ver : _ver; _ver++; string mbAssemblyDirective = $@"[assembly:ModelsBuilderAssembly(IsInMemory = true, SourceHash = ""{currentHash}"")] [assembly:System.Reflection.AssemblyVersion(""0.0.0.{ver}"")]"; code = code.Replace("//ASSATTR", mbAssemblyDirective); File.WriteAllText(modelsSrcFile, code); // generate proj, save var projFiles = new Dictionary <string, string> { { "models.generated.cs", code } }; var proj = GenerateModelsProj(projFiles); File.WriteAllText(projFile, proj); // compile and register try { var assemblyPath = GetOutputAssemblyPath(currentHash); RoslynCompiler.CompileToFile(projFile, assemblyPath); assembly = ReloadAssembly(assemblyPath); File.WriteAllText(dllPathFile, assemblyPath); File.WriteAllText(modelsHashFile, currentHash); TryDeleteUnusedAssemblies(dllPathFile); } catch { ClearOnFailingToCompile(dllPathFile, modelsHashFile, projFile); throw; } _logger.LogDebug("Done rebuilding."); return(assembly); }
public ModelsBuilderApiController(UmbracoServices umbracoServices) { _umbracoServices = umbracoServices; }
public LightInjectUmbracoRegister() { _registrations = UmbracoServices.GetAllRegistrations().ToList(); }
public UnityUmbracoRegister(IUnityContainer container) { _container = container; _registrations = UmbracoServices.GetAllRegistrations().ToList(); }