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

Reusing the same part instances #3310

Merged
merged 3 commits into from
Mar 13, 2019
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using OrchardCore.ContentManagement;
using OrchardCore.ContentManagement;
using System.ComponentModel.DataAnnotations;

namespace OrchardCore.Title.Model
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Collections.Generic;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

Expand All @@ -9,6 +10,8 @@ namespace OrchardCore.ContentManagement
/// </summary>
public class ContentElement : IContent
{
internal Dictionary<string, ContentElement> _elements = new Dictionary<string, ContentElement>();

protected ContentElement() : this(new JObject())
{
}
Expand All @@ -33,8 +36,7 @@ protected ContentElement(JObject data)
/// <param name="name">The name of the property to look for.</param>
public bool Has(string name)
{
JToken value;
return Data.TryGetValue(name, out value);
return Data.ContainsKey(name);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ public static bool Has<TElement>(this ContentElement contentElement) where TElem
/// <returns>The content element instance or <code>null</code> if it doesn't exist.</returns>
public static ContentElement Get(this ContentElement contentElement, Type contentElementType, string name)
{
if (contentElement._elements.TryGetValue(name, out var element))
{
return element;
}

var elementData = contentElement.Data[name] as JObject;

if (elementData == null)
Expand All @@ -52,6 +57,8 @@ public static ContentElement Get(this ContentElement contentElement, Type conten
result.Data = elementData;
result.ContentItem = contentElement.ContentItem;

contentElement._elements[name] = result;

return result;
}

Expand All @@ -67,10 +74,11 @@ public static ContentElement Get(this ContentElement contentElement, Type conten

if (existing == null)
{
existing = new TElement();
existing.ContentItem = contentElement.ContentItem;
contentElement.Data[name] = existing.Data;
return existing;
var newElement = new TElement();
newElement.ContentItem = contentElement.ContentItem;
contentElement.Data[name] = newElement.Data;
contentElement._elements[name] = newElement;
return newElement;
}

return existing;
Expand All @@ -91,6 +99,7 @@ public static ContentElement Weld(this ContentElement contentElement, string nam
element.ContentItem = contentElement.ContentItem;

contentElement.Data[name] = element.Data;
contentElement._elements[name] = element;
}

return contentElement;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,156 +4,137 @@ namespace OrchardCore.ContentManagement.Handlers
{
public abstract class ContentPartHandler<TPart> : IContentPartHandler where TPart : ContentPart, new()
{
async Task IContentPartHandler.ActivatedAsync(ActivatedContentContext context, ContentPart part)
Task IContentPartHandler.ActivatedAsync(ActivatedContentContext context, ContentPart part)
{
if (part is TPart)
{
await ActivatedAsync(context, (TPart)part);
}
return part is TPart tpart
? ActivatedAsync(context, tpart)
: Task.CompletedTask;
}

async Task IContentPartHandler.ActivatingAsync(ActivatingContentContext context, ContentPart part)
Task IContentPartHandler.ActivatingAsync(ActivatingContentContext context, ContentPart part)
{
if (part is TPart)
{
await ActivatingAsync(context, (TPart)part);
}
return part is TPart tpart
? ActivatingAsync(context, tpart)
: Task.CompletedTask;
}

async Task IContentPartHandler.InitializingAsync(InitializingContentContext context, ContentPart part)
Task IContentPartHandler.InitializingAsync(InitializingContentContext context, ContentPart part)
{
if (part is TPart)
{
await InitializingAsync(context, (TPart)part);
}
return part is TPart tpart
? InitializingAsync(context, tpart)
: Task.CompletedTask;
}

async Task IContentPartHandler.InitializedAsync(InitializingContentContext context, ContentPart part)
Task IContentPartHandler.InitializedAsync(InitializingContentContext context, ContentPart part)
{
if (part is TPart)
{
await InitializedAsync(context, (TPart)part);
}
return part is TPart tpart
? InitializedAsync(context, tpart)
: Task.CompletedTask;
}

async Task IContentPartHandler.CreatingAsync(CreateContentContext context, ContentPart part)
Task IContentPartHandler.CreatingAsync(CreateContentContext context, ContentPart part)
{
if (part is TPart)
{
await CreatingAsync(context, (TPart)part);
}
return part is TPart tpart
? CreatingAsync(context, tpart)
: Task.CompletedTask;
}

async Task IContentPartHandler.CreatedAsync(CreateContentContext context, ContentPart part)
Task IContentPartHandler.CreatedAsync(CreateContentContext context, ContentPart part)
{
if (part is TPart)
{
await CreatedAsync(context, (TPart)part);
}
return part is TPart tpart
? CreatedAsync(context, tpart)
: Task.CompletedTask;
}

async Task IContentPartHandler.LoadingAsync(LoadContentContext context, ContentPart part)
Task IContentPartHandler.LoadingAsync(LoadContentContext context, ContentPart part)
{
if (part is TPart)
{
await LoadingAsync(context, (TPart)part);
}
return part is TPart tpart
? LoadingAsync(context, tpart)
: Task.CompletedTask;
}

async Task IContentPartHandler.LoadedAsync(LoadContentContext context, ContentPart part)
Task IContentPartHandler.LoadedAsync(LoadContentContext context, ContentPart part)
{
if (part is TPart)
{
await LoadedAsync(context, (TPart)part);
}
return part is TPart tpart
? LoadedAsync(context, tpart)
: Task.CompletedTask;
}

async Task IContentPartHandler.UpdatingAsync(UpdateContentContext context, ContentPart part)
Task IContentPartHandler.UpdatingAsync(UpdateContentContext context, ContentPart part)
{
if (part is TPart)
{
await UpdatingAsync(context, (TPart)part);
}
return part is TPart tpart
? UpdatingAsync(context, tpart)
: Task.CompletedTask;
}

async Task IContentPartHandler.UpdatedAsync(UpdateContentContext context, ContentPart part)
Task IContentPartHandler.UpdatedAsync(UpdateContentContext context, ContentPart part)
{
if (part is TPart)
{
await UpdatedAsync(context, (TPart)part);
}
return part is TPart tpart
? UpdatedAsync(context, tpart)
: Task.CompletedTask;
}

async Task IContentPartHandler.VersioningAsync(VersionContentContext context, ContentPart existing, ContentPart building)
Task IContentPartHandler.VersioningAsync(VersionContentContext context, ContentPart existing, ContentPart building)
{
if (existing is TPart && building is TPart)
{
await VersioningAsync(context, (TPart)existing, (TPart)building);
}
return existing is TPart texisting && building is TPart tbuilding
? VersioningAsync(context, texisting, tbuilding)
: Task.CompletedTask;
}

async Task IContentPartHandler.VersionedAsync(VersionContentContext context, ContentPart existing, ContentPart building)
Task IContentPartHandler.VersionedAsync(VersionContentContext context, ContentPart existing, ContentPart building)
{
if (existing is TPart && building is TPart)
{
await VersionedAsync(context, (TPart)existing, (TPart)building);
}
return existing is TPart texisting && building is TPart tbuilding
? VersionedAsync(context, texisting, tbuilding)
: Task.CompletedTask;
}

async Task IContentPartHandler.PublishingAsync(PublishContentContext context, ContentPart part)
Task IContentPartHandler.PublishingAsync(PublishContentContext context, ContentPart part)
{
if (part is TPart)
{
await PublishingAsync(context, (TPart)part);
}
return part is TPart tpart
? PublishingAsync(context, tpart)
: Task.CompletedTask;
}

async Task IContentPartHandler.PublishedAsync(PublishContentContext context, ContentPart part)
Task IContentPartHandler.PublishedAsync(PublishContentContext context, ContentPart part)
{
if (part is TPart)
{
await PublishedAsync(context, (TPart)part);
}
return part is TPart tpart
? PublishedAsync(context, tpart)
: Task.CompletedTask;
}

async Task IContentPartHandler.UnpublishingAsync(PublishContentContext context, ContentPart part)
Task IContentPartHandler.UnpublishingAsync(PublishContentContext context, ContentPart part)
{
if (part is TPart)
{
await UnpublishingAsync(context, (TPart)part);
}
return part is TPart tpart
? UnpublishingAsync(context, tpart)
: Task.CompletedTask;
}

async Task IContentPartHandler.UnpublishedAsync(PublishContentContext context, ContentPart part)
Task IContentPartHandler.UnpublishedAsync(PublishContentContext context, ContentPart part)
{
if (part is TPart)
{
await UnpublishedAsync(context, (TPart)part);
}
return part is TPart tpart
? UnpublishedAsync(context, tpart)
: Task.CompletedTask;
}

async Task IContentPartHandler.RemovingAsync(RemoveContentContext context, ContentPart part)
Task IContentPartHandler.RemovingAsync(RemoveContentContext context, ContentPart part)
{
if (part is TPart)
{
await RemovingAsync(context, (TPart)part);
}
return part is TPart tpart
? RemovingAsync(context, tpart)
: Task.CompletedTask;
}

async Task IContentPartHandler.RemovedAsync(RemoveContentContext context, ContentPart part)
Task IContentPartHandler.RemovedAsync(RemoveContentContext context, ContentPart part)
{
if (part is TPart)
{
await RemovedAsync(context, (TPart)part);
}
return part is TPart tpart
? RemovedAsync(context, tpart)
: Task.CompletedTask;
}

async Task IContentPartHandler.GetContentItemAspectAsync(ContentItemAspectContext context, ContentPart part)
Task IContentPartHandler.GetContentItemAspectAsync(ContentItemAspectContext context, ContentPart part)
{
if (part is TPart)
{
await GetContentItemAspectAsync(context, (TPart)part);
}
return part is TPart tpart
? GetContentItemAspectAsync(context, tpart)
: Task.CompletedTask;
}

public virtual Task ActivatedAsync(ActivatedContentContext context, TPart instance) => Task.CompletedTask;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,11 +167,14 @@ public override async Task LoadingAsync(LoadContentContext context)
foreach (var typePartDefinition in contentTypeDefinition.Parts)
{
var partName = typePartDefinition.PartDefinition.Name;
var part = context.ContentItem.Get<ContentPart>(typePartDefinition.Name);
var activator = _contentPartFactory.GetTypeActivator(partName);

var part = context.ContentItem.Get(activator.Type, typePartDefinition.Name) as ContentPart;

// If no existing part was not found in the content item, create a new one
if (part == null)
{
part = _contentPartFactory.GetTypeActivator(partName).CreateInstance();
part = activator.CreateInstance();
context.ContentItem.Weld(typePartDefinition.Name, part);
}

Expand All @@ -183,8 +186,8 @@ public override async Task LoadingAsync(LoadContentContext context)

if (!part.Has(fieldName))
{
var activator = _contentFieldFactory.GetTypeActivator(partFieldDefinition.FieldDefinition.Name);
context.ContentItem.Get<ContentPart>(typePartDefinition.Name).Weld(fieldName, activator.CreateInstance());
var fieldActivator = _contentFieldFactory.GetTypeActivator(partFieldDefinition.FieldDefinition.Name);
context.ContentItem.Get<ContentPart>(typePartDefinition.Name).Weld(fieldName, fieldActivator.CreateInstance());
}
}
}
Expand Down