1
- using Umbraco . Cms . Core . Models ;
1
+ using Microsoft . Extensions . Logging ;
2
+ using Umbraco . Cms . Core . Cache ;
3
+ using Umbraco . Cms . Core . Models ;
2
4
using Umbraco . Cms . Core . Models . PublishedContent ;
3
5
using Umbraco . Cms . Core . PublishedCache ;
6
+ using Umbraco . Extensions ;
4
7
5
8
namespace Umbraco . Cms . Infrastructure . HybridCache . Factories ;
6
9
10
+ /// <summary>
11
+ /// Defines a factory to create <see cref="IPublishedContent"/> and <see cref="IPublishedMember"/> from a <see cref="ContentCacheNode"/> or <see cref="IMember"/>.
12
+ /// </summary>
7
13
internal sealed class PublishedContentFactory : IPublishedContentFactory
8
14
{
9
15
private readonly IElementsCache _elementsCache ;
10
16
private readonly IVariationContextAccessor _variationContextAccessor ;
11
17
private readonly IPublishedContentTypeCache _publishedContentTypeCache ;
18
+ private readonly ILogger < PublishedContentFactory > _logger ;
19
+ private readonly AppCaches _appCaches ;
12
20
13
-
21
+ /// <summary>
22
+ /// Initializes a new instance of the <see cref="PublishedContentFactory"/> class.
23
+ /// </summary>
14
24
public PublishedContentFactory (
15
25
IElementsCache elementsCache ,
16
26
IVariationContextAccessor variationContextAccessor ,
17
- IPublishedContentTypeCache publishedContentTypeCache )
27
+ IPublishedContentTypeCache publishedContentTypeCache ,
28
+ ILogger < PublishedContentFactory > logger ,
29
+ AppCaches appCaches )
18
30
{
19
31
_elementsCache = elementsCache ;
20
32
_variationContextAccessor = variationContextAccessor ;
21
33
_publishedContentTypeCache = publishedContentTypeCache ;
34
+ _logger = logger ;
35
+ _appCaches = appCaches ;
22
36
}
23
37
38
+ /// <inheritdoc/>
24
39
public IPublishedContent ? ToIPublishedContent ( ContentCacheNode contentCacheNode , bool preview )
25
40
{
26
- IPublishedContentType contentType = _publishedContentTypeCache . Get ( PublishedItemType . Content , contentCacheNode . ContentTypeId ) ;
41
+ var cacheKey = $ "{ nameof ( PublishedContentFactory ) } DocumentCache_{ contentCacheNode . Id } _{ preview } ";
42
+ IPublishedContent ? publishedContent = _appCaches . RequestCache . GetCacheItem < IPublishedContent ? > ( cacheKey ) ;
43
+ if ( publishedContent is not null )
44
+ {
45
+ _logger . LogDebug (
46
+ "Using cached IPublishedContent for document {ContentCacheNodeName} ({ContentCacheNodeId})." ,
47
+ contentCacheNode . Data ? . Name ?? "No Name" ,
48
+ contentCacheNode . Id ) ;
49
+ return publishedContent ;
50
+ }
51
+
52
+ _logger . LogDebug (
53
+ "Creating IPublishedContent for document {ContentCacheNodeName} ({ContentCacheNodeId})." ,
54
+ contentCacheNode . Data ? . Name ?? "No Name" ,
55
+ contentCacheNode . Id ) ;
56
+
57
+ IPublishedContentType contentType =
58
+ _publishedContentTypeCache . Get ( PublishedItemType . Content , contentCacheNode . ContentTypeId ) ;
27
59
var contentNode = new ContentNode (
28
60
contentCacheNode . Id ,
29
61
contentCacheNode . Key ,
@@ -34,19 +66,42 @@ public PublishedContentFactory(
34
66
preview ? contentCacheNode . Data : null ,
35
67
preview ? null : contentCacheNode . Data ) ;
36
68
37
- IPublishedContent ? model = GetModel ( contentNode , preview ) ;
69
+ publishedContent = GetModel ( contentNode , preview ) ;
38
70
39
71
if ( preview )
40
72
{
41
- return model ?? GetPublishedContentAsDraft ( model ) ;
73
+ publishedContent ??= GetPublishedContentAsDraft ( publishedContent ) ;
74
+ }
75
+
76
+ if ( publishedContent is not null )
77
+ {
78
+ _appCaches . RequestCache . Set ( cacheKey , publishedContent ) ;
42
79
}
43
80
44
- return model ;
81
+ return publishedContent ;
45
82
}
46
83
84
+ /// <inheritdoc/>
47
85
public IPublishedContent ? ToIPublishedMedia ( ContentCacheNode contentCacheNode )
48
86
{
49
- IPublishedContentType contentType = _publishedContentTypeCache . Get ( PublishedItemType . Media , contentCacheNode . ContentTypeId ) ;
87
+ var cacheKey = $ "{ nameof ( PublishedContentFactory ) } MediaCache_{ contentCacheNode . Id } ";
88
+ IPublishedContent ? publishedContent = _appCaches . RequestCache . GetCacheItem < IPublishedContent ? > ( cacheKey ) ;
89
+ if ( publishedContent is not null )
90
+ {
91
+ _logger . LogDebug (
92
+ "Using cached IPublishedContent for media {ContentCacheNodeName} ({ContentCacheNodeId})." ,
93
+ contentCacheNode . Data ? . Name ?? "No Name" ,
94
+ contentCacheNode . Id ) ;
95
+ return publishedContent ;
96
+ }
97
+
98
+ _logger . LogDebug (
99
+ "Creating IPublishedContent for media {ContentCacheNodeName} ({ContentCacheNodeId})." ,
100
+ contentCacheNode . Data ? . Name ?? "No Name" ,
101
+ contentCacheNode . Id ) ;
102
+
103
+ IPublishedContentType contentType =
104
+ _publishedContentTypeCache . Get ( PublishedItemType . Media , contentCacheNode . ContentTypeId ) ;
50
105
var contentNode = new ContentNode (
51
106
contentCacheNode . Id ,
52
107
contentCacheNode . Key ,
@@ -57,14 +112,40 @@ public PublishedContentFactory(
57
112
null ,
58
113
contentCacheNode . Data ) ;
59
114
60
- return GetModel ( contentNode , false ) ;
115
+ publishedContent = GetModel ( contentNode , false ) ;
116
+
117
+ if ( publishedContent is not null )
118
+ {
119
+ _appCaches . RequestCache . Set ( cacheKey , publishedContent ) ;
120
+ }
121
+
122
+ return publishedContent ;
61
123
}
62
124
125
+ /// <inheritdoc/>
63
126
public IPublishedMember ToPublishedMember ( IMember member )
64
127
{
65
- IPublishedContentType contentType = _publishedContentTypeCache . Get ( PublishedItemType . Member , member . ContentTypeId ) ;
128
+ string cacheKey = $ "{ nameof ( PublishedContentFactory ) } MemberCache_{ member . Id } ";
129
+ IPublishedMember ? publishedMember = _appCaches . RequestCache . GetCacheItem < IPublishedMember ? > ( cacheKey ) ;
130
+ if ( publishedMember is not null )
131
+ {
132
+ _logger . LogDebug (
133
+ "Using cached IPublishedMember for member {MemberName} ({MemberId})." ,
134
+ member . Username ,
135
+ member . Id ) ;
136
+
137
+ return publishedMember ;
138
+ }
139
+
140
+ _logger . LogDebug (
141
+ "Creating IPublishedMember for member {MemberName} ({MemberId})." ,
142
+ member . Username ,
143
+ member . Id ) ;
144
+
145
+ IPublishedContentType contentType =
146
+ _publishedContentTypeCache . Get ( PublishedItemType . Member , member . ContentTypeId ) ;
66
147
67
- // Members are only "mapped" never cached, so these default values are a bit wierd , but they are not used.
148
+ // Members are only "mapped" never cached, so these default values are a bit weird , but they are not used.
68
149
var contentData = new ContentData (
69
150
member . Name ,
70
151
null ,
@@ -85,7 +166,11 @@ public IPublishedMember ToPublishedMember(IMember member)
85
166
contentType ,
86
167
null ,
87
168
contentData ) ;
88
- return new PublishedMember ( member , contentNode , _elementsCache , _variationContextAccessor ) ;
169
+ publishedMember = new PublishedMember ( member , contentNode , _elementsCache , _variationContextAccessor ) ;
170
+
171
+ _appCaches . RequestCache . Set ( cacheKey , publishedMember ) ;
172
+
173
+ return publishedMember ;
89
174
}
90
175
91
176
private static Dictionary < string , PropertyData [ ] > GetPropertyValues ( IPublishedContentType contentType , IMember member )
@@ -134,7 +219,6 @@ private static void AddIf(IPublishedContentType contentType, IDictionary<string,
134
219
_variationContextAccessor ) ;
135
220
}
136
221
137
-
138
222
private static IPublishedContent ? GetPublishedContentAsDraft ( IPublishedContent ? content ) =>
139
223
content == null ? null :
140
224
// an object in the cache is either an IPublishedContentOrMedia,
@@ -149,7 +233,7 @@ private static PublishedContent UnwrapIPublishedContent(IPublishedContent conten
149
233
content = wrapped . Unwrap ( ) ;
150
234
}
151
235
152
- if ( ! ( content is PublishedContent inner ) )
236
+ if ( content is not PublishedContent inner )
153
237
{
154
238
throw new InvalidOperationException ( "Innermost content is not PublishedContent." ) ;
155
239
}
0 commit comments