Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add IContextCache to deploy connectors #13287

Merged
merged 7 commits into from Oct 25, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
73 changes: 36 additions & 37 deletions src/Umbraco.Core/Deploy/ArtifactBase.cs
@@ -1,50 +1,49 @@
namespace Umbraco.Cms.Core.Deploy
namespace Umbraco.Cms.Core.Deploy;

/// <summary>
/// Provides a base class to all artifacts.
/// </summary>
public abstract class ArtifactBase<TUdi> : IArtifact
where TUdi : Udi
{
/// <summary>
/// Provides a base class to all artifacts.
/// </summary>
public abstract class ArtifactBase<TUdi> : IArtifact
where TUdi : Udi
protected ArtifactBase(TUdi udi, IEnumerable<ArtifactDependency>? dependencies = null)
{
protected ArtifactBase(TUdi udi, IEnumerable<ArtifactDependency>? dependencies = null)
{
Udi = udi ?? throw new ArgumentNullException("udi");
Name = Udi.ToString();
Udi = udi ?? throw new ArgumentNullException("udi");
Name = Udi.ToString();

_dependencies = dependencies ?? Enumerable.Empty<ArtifactDependency>();
_checksum = new Lazy<string>(GetChecksum);
}

private readonly Lazy<string> _checksum;
_dependencies = dependencies ?? Enumerable.Empty<ArtifactDependency>();
_checksum = new Lazy<string>(GetChecksum);
}

private IEnumerable<ArtifactDependency> _dependencies;
private readonly Lazy<string> _checksum;

protected abstract string GetChecksum();
private IEnumerable<ArtifactDependency> _dependencies;

Udi IArtifactSignature.Udi => Udi;
protected abstract string GetChecksum();

public TUdi Udi { get; set; }
Udi IArtifactSignature.Udi => Udi;

public string Checksum => _checksum.Value;
public TUdi Udi { get; set; }

/// <summary>
/// Prevents the <see cref="Checksum" /> property from being serialized.
/// </summary>
/// <remarks>
/// Note that we can't use <see cref="NonSerializedAttribute"/> here as that works only on fields, not properties. And we want to avoid using [JsonIgnore]
/// as that would require an external dependency in Umbraco.Cms.Core.
/// So using this method of excluding properties from serialized data, documented here: https://www.newtonsoft.com/json/help/html/ConditionalProperties.htm
/// </remarks>
public bool ShouldSerializeChecksum() => false;
public string Checksum => _checksum.Value;

public IEnumerable<ArtifactDependency> Dependencies
{
get => _dependencies;
set => _dependencies = value.OrderBy(x => x.Udi);
}
/// <summary>
/// Prevents the <see cref="Checksum" /> property from being serialized.
/// </summary>
/// <remarks>
/// Note that we can't use <see cref="NonSerializedAttribute"/> here as that works only on fields, not properties. And we want to avoid using [JsonIgnore]
/// as that would require an external dependency in Umbraco.Cms.Core.
/// So using this method of excluding properties from serialized data, documented here: https://www.newtonsoft.com/json/help/html/ConditionalProperties.htm
/// </remarks>
public bool ShouldSerializeChecksum() => false;

public IEnumerable<ArtifactDependency> Dependencies
{
get => _dependencies;
set => _dependencies = value.OrderBy(x => x.Udi);
}

public string Name { get; set; }
public string Name { get; set; }

public string Alias { get; set; } = string.Empty;
}
public string Alias { get; set; } = string.Empty;
}
37 changes: 37 additions & 0 deletions src/Umbraco.Core/Deploy/ArtifactDeployState.cs
Expand Up @@ -44,3 +44,40 @@ public abstract class ArtifactDeployState
/// </remarks>
protected abstract IArtifact GetArtifactAsIArtifact();
}

/// <summary>
/// Represent the state of an artifact being deployed.
/// </summary>
/// <typeparam name="TArtifact">The type of the artifact.</typeparam>
/// <typeparam name="TEntity">The type of the entity.</typeparam>
public class ArtifactDeployState<TArtifact, TEntity> : ArtifactDeployState
where TArtifact : IArtifact
{
/// <summary>
/// Initializes a new instance of the <see cref="ArtifactDeployState{TArtifact,TEntity}" /> class.
/// </summary>
/// <param name="art">The artifact.</param>
/// <param name="entity">The entity.</param>
/// <param name="connector">The service connector deploying the artifact.</param>
/// <param name="nextPass">The next pass number.</param>
public ArtifactDeployState(TArtifact art, TEntity? entity, IServiceConnector connector, int nextPass)
{
Artifact = art;
Entity = entity;
Connector = connector;
NextPass = nextPass;
}

/// <summary>
/// Gets or sets the artifact.
/// </summary>
public new TArtifact Artifact { get; set; }

/// <summary>
/// Gets or sets the entity.
/// </summary>
public TEntity? Entity { get; set; }

/// <inheritdoc />
protected sealed override IArtifact GetArtifactAsIArtifact() => Artifact;
}
38 changes: 0 additions & 38 deletions src/Umbraco.Core/Deploy/ArtifactDeployStateOfTArtifactTEntity.cs

This file was deleted.

31 changes: 31 additions & 0 deletions src/Umbraco.Core/Deploy/IContextCache.cs
@@ -0,0 +1,31 @@
namespace Umbraco.Cms.Core.Deploy;

/// <summary>
/// Represents a context cache used by Deploy operations.
/// </summary>
public interface IContextCache
{
/// <summary>
/// Creates the item on the context cache using the specified <paramref name="key" />.
/// </summary>
/// <typeparam name="T">The type of the cached item.</typeparam>
/// <param name="key">The key of the cached item.</param>
/// <param name="item">The item.</param>
void Create<T>(string key, T item);

/// <summary>
/// Gets an item from the context cache or creates and stores it using the specified <paramref name="key" />.
/// </summary>
/// <typeparam name="T">The type of the cached item.</typeparam>
/// <param name="key">The key of the cached item.</param>
/// <param name="factory">The factory method to create the item (if it doesn't exist yet).</param>
/// <returns>
/// The item.
/// </returns>
T? GetOrCreate<T>(string key, Func<T?> factory);

/// <summary>
/// Clears all cached items on this context.
/// </summary>
void Clear();
}
62 changes: 46 additions & 16 deletions src/Umbraco.Core/Deploy/IDataTypeConfigurationConnector.cs
@@ -1,37 +1,67 @@
using System.Diagnostics.CodeAnalysis;
using Umbraco.Cms.Core.Models;

namespace Umbraco.Cms.Core.Deploy;

/// <summary>
/// Defines methods that can convert data type configuration to / from an environment-agnostic string.
/// Defines methods that can convert data type configuration to / from an environment-agnostic string.
/// </summary>
/// <remarks>
/// Configuration may contain values such as content identifiers, that would be local
/// to one environment, and need to be converted in order to be deployed.
/// Configuration may contain values such as content identifiers, that would be local
/// to one environment, and need to be converted in order to be deployed.
/// </remarks>
[SuppressMessage(
"ReSharper",
"UnusedMember.Global",
Justification = "This is actual only used by Deploy, but we don't want third parties to have references on deploy, that's why this interface is part of core.")]
public interface IDataTypeConfigurationConnector
{
/// <summary>
/// Gets the property editor aliases that the value converter supports by default.
/// Gets the property editor aliases that the value converter supports by default.
/// </summary>
/// <value>
/// The property editor aliases.
/// </value>
IEnumerable<string> PropertyEditorAliases { get; }

/// <summary>
/// Gets the artifact datatype configuration corresponding to the actual datatype configuration.
/// Gets the artifact configuration value corresponding to a data type configuration and gather dependencies.
/// </summary>
/// <param name="dataType">The datatype.</param>
/// <param name="dataType">The data type.</param>
/// <param name="dependencies">The dependencies.</param>
string? ToArtifact(IDataType dataType, ICollection<ArtifactDependency> dependencies);
/// <returns>
/// The artifact configuration value.
/// </returns>
[Obsolete("Use the overload accepting IContextCache instead. This overload will be removed in a future version.")]
string? ToArtifact(IDataType dataType, ICollection<ArtifactDependency> dependencies)
=> ToArtifact(dataType, dependencies, PassThroughCache.Instance);

/// <summary>
/// Gets the actual datatype configuration corresponding to the artifact configuration.
/// Gets the artifact configuration value corresponding to a data type configuration and gather dependencies.
/// </summary>
/// <param name="dataType">The datatype.</param>
/// <param name="configuration">The artifact configuration.</param>
object? FromArtifact(IDataType dataType, string? configuration);
/// <param name="dataType">The data type.</param>
/// <param name="dependencies">The dependencies.</param>
/// <param name="contextCache">The context cache.</param>
/// <returns>
/// The artifact configuration value.
/// </returns>
string? ToArtifact(IDataType dataType, ICollection<ArtifactDependency> dependencies, IContextCache contextCache);

/// <summary>
/// Gets the data type configuration corresponding to an artifact configuration value.
/// </summary>
/// <param name="dataType">The data type.</param>
/// <param name="configuration">The artifact configuration value.</param>
/// <returns>
/// The data type configuration.
/// </returns>
[Obsolete("Use the overload accepting IContextCache instead. This overload will be removed in a future version.")]
object? FromArtifact(IDataType dataType, string? configuration)
=> FromArtifact(dataType, configuration, PassThroughCache.Instance);

/// <summary>
/// Gets the data type configuration corresponding to an artifact configuration value.
/// </summary>
/// <param name="dataType">The data type.</param>
/// <param name="configuration">The artifact configuration value.</param>
/// <param name="contextCache">The context cache.</param>
/// <returns>
/// The data type configuration.
/// </returns>
object? FromArtifact(IDataType dataType, string? configuration, IContextCache contextCache);
}