Example #1
0
        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);
        }
Example #2
0
    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;
 }
Example #5
0
 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;
                }
            }
        }
Example #7
0
        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);
        }
Example #8
0
        /// <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;
                }
            }
        }
Example #9
0
 public ModelsGenerator(UmbracoServices umbracoService, IModelsBuilderConfig config, OutOfDateModelsStatus outOfDateModels)
 {
     _umbracoService  = umbracoService;
     _config          = config;
     _outOfDateModels = outOfDateModels;
 }
Example #10
0
        // 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;
 }
Example #12
0
 public LightInjectUmbracoRegister()
 {
     _registrations = UmbracoServices.GetAllRegistrations().ToList();
 }
Example #13
0
 public UnityUmbracoRegister(IUnityContainer container)
 {
     _container     = container;
     _registrations = UmbracoServices.GetAllRegistrations().ToList();
 }