using System; using System.Collections.Generic; using Umbraco.Core.Models.PublishedContent; namespace Umbraco.Core { /// /// Provides extension methods for . /// public static class PublishedModelFactoryExtensions { /// /// Returns true if the current is an implementation of /// /// /// public static bool IsLiveFactory(this IPublishedModelFactory factory) => factory is ILivePublishedModelFactory; /// /// Executes an action with a safe live factory /// /// /// If the factory is a live factory, ensures it is refreshed and locked while executing the action. /// public static void WithSafeLiveFactory(this IPublishedModelFactory factory, Action action) { if (factory is ILivePublishedModelFactory liveFactory) { lock (liveFactory.SyncRoot) { //Call refresh on the live factory to re-compile the models liveFactory.Refresh(); action(); } } else { action(); } } /// /// Creates a strongly typed model while checking if the factory is and if a refresh flag has been set, in which /// case the models will be recompiled before model creation /// /// /// /// internal static IPublishedContent CreateModelWithSafeLiveFactoryRefreshCheck(this IPublishedModelFactory factory, IPublishedContent content) { if (factory is ILivePublishedModelFactory liveFactory && _refresh) { lock (liveFactory.SyncRoot) { if (_refresh) { _refresh = false; //Call refresh on the live factory to re-compile the models liveFactory.Refresh(); } } } var model = factory.CreateModel(content); if (model == null) throw new Exception("Factory returned null."); // if factory returns a different type, throw if (!(model is IPublishedContent publishedContent)) throw new Exception($"Factory returned model of type {model.GetType().FullName} which does not implement IPublishedContent."); return publishedContent; } /// /// Sets a flag to re-compile the models if the is /// /// /// internal static void WithSafeLiveFactoryRefreshSet(this IPublishedModelFactory factory, Action action) { if (factory is ILivePublishedModelFactory liveFactory) { lock (liveFactory.SyncRoot) { _refresh = true; action(); } } else { action(); } } private static volatile bool _refresh = false; } }