Ensures the default PublishedModelFactory is always registered. Ensures AddModelsBuilder is done when adding the website (not required for the back office).

This commit is contained in:
Shannon
2021-02-01 16:53:24 +11:00
parent 624739e697
commit 2a41cec263
18 changed files with 165 additions and 128 deletions

View File

@@ -3,8 +3,8 @@ using System.Text;
using Microsoft.Extensions.Options;
using Umbraco.Core.Configuration;
using Umbraco.Core.Configuration.Models;
using Umbraco.Core.IO;
using Umbraco.Core.Hosting;
using Umbraco.Core.IO;
namespace Umbraco.ModelsBuilder.Embedded.Building
{

View File

@@ -85,8 +85,16 @@ namespace Umbraco.ModelsBuilder.Embedded.DependencyInjection
/// </summary>
public static IUmbracoBuilder AddModelsBuilder(this IUmbracoBuilder builder)
{
var umbServices = new UniqueServiceDescriptor(typeof(UmbracoServices), typeof(UmbracoServices), ServiceLifetime.Singleton);
if (builder.Services.Contains(umbServices))
{
// if this ext method is called more than once just exit
return builder;
}
builder.Services.Add(umbServices);
builder.AddPureLiveRazorEngine();
builder.Services.AddSingleton<UmbracoServices>();
// TODO: I feel like we could just do builder.AddNotificationHandler<ModelsBuilderNotificationHandler>() and it
// would automatically just register for all implemented INotificationHandler{T}?
@@ -96,13 +104,16 @@ namespace Umbraco.ModelsBuilder.Embedded.DependencyInjection
builder.AddNotificationHandler<UmbracoApplicationStarting, LiveModelsProvider>();
builder.AddNotificationHandler<UmbracoRequestEnd, LiveModelsProvider>();
builder.AddNotificationHandler<UmbracoApplicationStarting, OutOfDateModelsStatus>();
builder.Services.AddUnique<ModelsGenerator>();
builder.Services.AddUnique<LiveModelsProvider>();
builder.Services.AddUnique<OutOfDateModelsStatus>();
builder.Services.AddUnique<ModelsGenerationError>();
builder.Services.AddSingleton<ModelsGenerator>();
builder.Services.AddSingleton<LiveModelsProvider>();
builder.Services.AddSingleton<OutOfDateModelsStatus>();
builder.Services.AddSingleton<ModelsGenerationError>();
builder.Services.AddUnique<PureLiveModelFactory>();
builder.Services.AddUnique<IPublishedModelFactory>(factory =>
builder.Services.AddSingleton<PureLiveModelFactory>();
// This is what the community MB would replace, all of the above services are fine to be registered
// even if the community MB is in place.
builder.Services.AddSingleton<IPublishedModelFactory>(factory =>
{
ModelsBuilderSettings config = factory.GetRequiredService<IOptions<ModelsBuilderSettings>>().Value;
if (config.ModelsMode == ModelsMode.PureLive)
@@ -111,12 +122,7 @@ namespace Umbraco.ModelsBuilder.Embedded.DependencyInjection
}
else
{
TypeLoader typeLoader = factory.GetRequiredService<TypeLoader>();
IPublishedValueFallback publishedValueFallback = factory.GetRequiredService<IPublishedValueFallback>();
IEnumerable<Type> types = typeLoader
.GetTypes<PublishedElementModel>() // element models
.Concat(typeLoader.GetTypes<PublishedContentModel>()); // content models
return new PublishedModelFactory(types, publishedValueFallback);
return factory.CreateDefaultPublishedModelFactory();
}
});

View File

@@ -45,10 +45,7 @@ namespace Umbraco.ModelsBuilder.Embedded
/// <summary>
/// Handles the <see cref="UmbracoApplicationStarting"/> notification
/// </summary>
public void Handle(UmbracoApplicationStarting notification)
{
Install();
}
public void Handle(UmbracoApplicationStarting notification) => Install();
private void Install()
{

View File

@@ -53,7 +53,7 @@ namespace Umbraco.ModelsBuilder.Embedded
}
/// <summary>
/// Handles the <see cref="ServerVariablesParsing"/> notification
/// Handles the <see cref="ServerVariablesParsing"/> notification to add custom urls and MB mode
/// </summary>
public void Handle(ServerVariablesParsing notification)
{
@@ -93,7 +93,7 @@ namespace Umbraco.ModelsBuilder.Embedded
{
var settings = new Dictionary<string, object>
{
{"mode", _config.ModelsMode.ToString()}
{"mode", _config.ModelsMode.ToString() }
};
return settings;
@@ -188,13 +188,12 @@ namespace Umbraco.ModelsBuilder.Embedded
{
// both are pure - report, and if different versions, restart
// if same version... makes no sense... and better not restart (loops?)
var sourceVersion = notification.SourceType.Assembly.GetName().Version;
var modelVersion = notification.ModelType.Assembly.GetName().Version;
Version sourceVersion = notification.SourceType.Assembly.GetName().Version;
Version modelVersion = notification.ModelType.Assembly.GetName().Version;
notification.Message.Append(" Both view and content models are PureLive, with ");
notification.Message.Append(sourceVersion == modelVersion
? "same version. The application is in an unstable state and should be restarted."
: "different versions. The application is in an unstable state and is going to be restarted.");
notification.Restart = sourceVersion != modelVersion;
: "different versions. The application is in an unstable state and should be restarted.");
}
}
}

View File

@@ -1,10 +1,10 @@
using System;
using System;
using System.IO;
using System.Text;
using Microsoft.Extensions.Options;
using Umbraco.Core.Configuration;
using Umbraco.Core.Hosting;
using Umbraco.Core.Configuration.Models;
using Umbraco.Core.Hosting;
namespace Umbraco.ModelsBuilder.Embedded
{
@@ -13,6 +13,9 @@ namespace Umbraco.ModelsBuilder.Embedded
private readonly ModelsBuilderSettings _config;
private readonly IHostingEnvironment _hostingEnvironment;
/// <summary>
/// Initializes a new instance of the <see cref="ModelsGenerationError"/> class.
/// </summary>
public ModelsGenerationError(IOptions<ModelsBuilderSettings> config, IHostingEnvironment hostingEnvironment)
{
_config = config.Value;
@@ -22,7 +25,10 @@ namespace Umbraco.ModelsBuilder.Embedded
public void Clear()
{
var errFile = GetErrFile();
if (errFile == null) return;
if (errFile == null)
{
return;
}
// "If the file to be deleted does not exist, no exception is thrown."
File.Delete(errFile);
@@ -31,7 +37,10 @@ namespace Umbraco.ModelsBuilder.Embedded
public void Report(string message, Exception e)
{
var errFile = GetErrFile();
if (errFile == null) return;
if (errFile == null)
{
return;
}
var sb = new StringBuilder();
sb.Append(message);
@@ -47,14 +56,18 @@ namespace Umbraco.ModelsBuilder.Embedded
public string GetLastError()
{
var errFile = GetErrFile();
if (errFile == null) return null;
if (errFile == null)
{
return null;
}
try
{
return File.ReadAllText(errFile);
}
catch // accepted
catch
{
// accepted
return null;
}
}
@@ -63,7 +76,9 @@ namespace Umbraco.ModelsBuilder.Embedded
{
var modelsDirectory = _config.ModelsDirectoryAbsolute(_hostingEnvironment);
if (!Directory.Exists(modelsDirectory))
{
return null;
}
return Path.Combine(modelsDirectory, "models.err");
}

View File

@@ -8,19 +8,31 @@ using Umbraco.Web.Cache;
namespace Umbraco.ModelsBuilder.Embedded
{
/// <summary>
/// Used to track if ModelsBuilder models are out of date/stale
/// </summary>
public sealed class OutOfDateModelsStatus : INotificationHandler<UmbracoApplicationStarting>
{
private readonly ModelsBuilderSettings _config;
private readonly IHostingEnvironment _hostingEnvironment;
/// <summary>
/// Initializes a new instance of the <see cref="OutOfDateModelsStatus"/> class.
/// </summary>
public OutOfDateModelsStatus(IOptions<ModelsBuilderSettings> config, IHostingEnvironment hostingEnvironment)
{
_config = config.Value;
_hostingEnvironment = hostingEnvironment;
}
/// <summary>
/// Gets a value indicating whether flagging out of date models is enabled
/// </summary>
public bool IsEnabled => _config.FlagOutOfDateModels;
/// <summary>
/// Gets a value indicating whether models are out of date
/// </summary>
public bool IsOutOfDate
{
get
@@ -38,10 +50,7 @@ namespace Umbraco.ModelsBuilder.Embedded
/// <summary>
/// Handles the <see cref="UmbracoApplicationStarting"/> notification
/// </summary>
public void Handle(UmbracoApplicationStarting notification)
{
Install();
}
public void Handle(UmbracoApplicationStarting notification) => Install();
private void Install()
{

View File

@@ -20,6 +20,9 @@ namespace Umbraco.ModelsBuilder.Embedded
private readonly IPublishedContentTypeFactory _publishedContentTypeFactory;
private readonly IShortStringHelper _shortStringHelper;
/// <summary>
/// Initializes a new instance of the <see cref="UmbracoServices"/> class.
/// </summary>
public UmbracoServices(
IContentTypeService contentTypeService,
IMediaTypeService mediaTypeService,