using System.Linq; using System.Reflection; using Umbraco.Core.Configuration; using Umbraco.Core; using Umbraco.Core.Logging; using Umbraco.Core.Composing; using Umbraco.Core.Models.PublishedContent; using Umbraco.ModelsBuilder.Embedded.Building; using Umbraco.Core.Configuration.Models; using Microsoft.Extensions.Options; namespace Umbraco.ModelsBuilder.Embedded.Compose { [ComposeBefore(typeof(IPublishedCacheComposer))] [RuntimeLevel(MinLevel = RuntimeLevel.Run)] public sealed class ModelsBuilderComposer : ICoreComposer { private readonly ModelsBuilderConfig _config; public ModelsBuilderComposer(IOptions config) { _config = config.Value; } public void Compose(Composition composition) { var isLegacyModelsBuilderInstalled = IsLegacyModelsBuilderInstalled(); if (isLegacyModelsBuilderInstalled) { ComposeForLegacyModelsBuilder(composition); return; } composition.Components().Append(); composition.Register(Lifetime.Singleton); composition.RegisterUnique(); composition.RegisterUnique(); composition.RegisterUnique(); composition.RegisterUnique(); if (_config.ModelsMode == ModelsMode.PureLive) ComposeForLiveModels(composition); else if (_config.EnableFactory) ComposeForDefaultModelsFactory(composition); } private static bool IsLegacyModelsBuilderInstalled() { Assembly legacyMbAssembly = null; try { legacyMbAssembly = Assembly.Load("Umbraco.ModelsBuilder"); } catch (System.Exception) { //swallow exception, DLL must not be there } return legacyMbAssembly != null; } private void ComposeForLegacyModelsBuilder(Composition composition) { composition.Logger.Info("ModelsBuilder.Embedded is disabled, the external ModelsBuilder was detected."); composition.Components().Append(); composition.Dashboards().Remove(); } private void ComposeForDefaultModelsFactory(Composition composition) { composition.RegisterUnique(factory => { var typeLoader = factory.GetInstance(); var types = typeLoader .GetTypes() // element models .Concat(typeLoader.GetTypes()); // content models return new PublishedModelFactory(types); }); } private void ComposeForLiveModels(Composition composition) { composition.RegisterUnique(); // the following would add @using statement in every view so user's don't // have to do it - however, then noone understands where the @using statement // comes from, and it cannot be avoided / removed --- DISABLED // /* // no need for @using in views // note: // we are NOT using the in-code attribute here, config is required // because that would require parsing the code... and what if it changes? // we can AddGlobalImport not sure we can remove one anyways var modelsNamespace = Configuration.Config.ModelsNamespace; if (string.IsNullOrWhiteSpace(modelsNamespace)) modelsNamespace = Configuration.Config.DefaultModelsNamespace; System.Web.WebPages.Razor.WebPageRazorHost.AddGlobalImport(modelsNamespace); */ } } }