Make PublishedContentQueryAccessor usable (#11601)
* Make PublishedContentQueryAccessor usable Closes #11319 * Make xmldocs for IPublishedContentQueryAccessor more helpful.
This commit is contained in:
@@ -0,0 +1,19 @@
|
||||
using System;
|
||||
|
||||
namespace Umbraco.Cms.Core.DependencyInjection
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides access to a request scoped service provider when available for cases where
|
||||
/// IHttpContextAccessor is not available. e.g. No reference to AspNetCore.Http in core.
|
||||
/// </summary>
|
||||
public interface IScopedServiceProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets a request scoped service provider when available.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Can be null.
|
||||
/// </remarks>
|
||||
IServiceProvider ServiceProvider { get; }
|
||||
}
|
||||
}
|
||||
@@ -166,7 +166,9 @@ namespace Umbraco.Cms.Infrastructure.DependencyInjection
|
||||
builder.Services.AddScoped<ITagQuery, TagQuery>();
|
||||
|
||||
builder.Services.AddSingleton<IUmbracoTreeSearcherFields, UmbracoTreeSearcherFields>();
|
||||
builder.Services.AddSingleton<IPublishedContentQueryAccessor, PublishedContentQueryAccessor>();
|
||||
builder.Services.AddSingleton<IPublishedContentQueryAccessor, PublishedContentQueryAccessor>(sp =>
|
||||
new PublishedContentQueryAccessor(sp.GetRequiredService<IScopedServiceProvider>())
|
||||
);
|
||||
builder.Services.AddScoped<IPublishedContentQuery>(factory =>
|
||||
{
|
||||
var umbCtx = factory.GetRequiredService<IUmbracoContextAccessor>();
|
||||
|
||||
@@ -1,7 +1,18 @@
|
||||
using Umbraco.Cms.Infrastructure;
|
||||
|
||||
namespace Umbraco.Cms.Core
|
||||
{
|
||||
/// <remarks>
|
||||
/// Not intended for use in background threads where you should make use of <see cref="Umbraco.Cms.Core.Web.IUmbracoContextFactory.EnsureUmbracoContext"/>
|
||||
/// and instead resolve IPublishedContentQuery from a <see cref="Microsoft.Extensions.DependencyInjection.IServiceScope"/>
|
||||
/// e.g. using <see cref="Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.CreateScope"/>
|
||||
/// <example>
|
||||
/// <code>
|
||||
/// // Background thread example
|
||||
/// using UmbracoContextReference _ = _umbracoContextFactory.EnsureUmbracoContext();
|
||||
/// using IServiceScope serviceScope = _serviceProvider.CreateScope();
|
||||
/// IPublishedContentQuery query = serviceScope.ServiceProvider.GetRequiredService<IPublishedContentQuery>();
|
||||
/// </code>
|
||||
/// </example>
|
||||
/// </remarks>
|
||||
public interface IPublishedContentQueryAccessor
|
||||
{
|
||||
bool TryGetValue(out IPublishedContentQuery publishedContentQuery);
|
||||
|
||||
@@ -1,17 +1,21 @@
|
||||
using System;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Umbraco.Cms.Core.DependencyInjection;
|
||||
|
||||
namespace Umbraco.Cms.Core
|
||||
{
|
||||
public class PublishedContentQueryAccessor : IPublishedContentQueryAccessor
|
||||
{
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
private readonly IScopedServiceProvider _scopedServiceProvider;
|
||||
|
||||
public PublishedContentQueryAccessor(IServiceProvider serviceProvider) => _serviceProvider = serviceProvider;
|
||||
[Obsolete("Please use alternative constructor")]
|
||||
public PublishedContentQueryAccessor(IServiceProvider serviceProvider) => _scopedServiceProvider = serviceProvider.GetRequiredService<IScopedServiceProvider>();
|
||||
|
||||
public PublishedContentQueryAccessor(IScopedServiceProvider scopedServiceProvider) => _scopedServiceProvider = scopedServiceProvider;
|
||||
|
||||
public bool TryGetValue(out IPublishedContentQuery publishedContentQuery)
|
||||
{
|
||||
publishedContentQuery = _serviceProvider.GetRequiredService<IPublishedContentQuery>();
|
||||
publishedContentQuery = _scopedServiceProvider.ServiceProvider?.GetService<IPublishedContentQuery>();
|
||||
|
||||
return publishedContentQuery is not null;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
using System;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Umbraco.Cms.Core.DependencyInjection;
|
||||
|
||||
namespace Umbraco.Cms.Web.Common.DependencyInjection
|
||||
{
|
||||
/// <inheritdoc />
|
||||
internal class ScopedServiceProvider : IScopedServiceProvider
|
||||
{
|
||||
private readonly IHttpContextAccessor _accessor;
|
||||
|
||||
public ScopedServiceProvider(IHttpContextAccessor accessor) => _accessor = accessor;
|
||||
|
||||
/// <inheritdoc />
|
||||
public IServiceProvider ServiceProvider => _accessor.HttpContext?.RequestServices;
|
||||
}
|
||||
}
|
||||
@@ -349,6 +349,7 @@ namespace Umbraco.Extensions
|
||||
builder.Services.AddSingleton<ContentModelBinder>();
|
||||
|
||||
builder.Services.AddSingleton<IUmbracoHelperAccessor, UmbracoHelperAccessor>();
|
||||
builder.Services.AddSingleton<IScopedServiceProvider, ScopedServiceProvider>();
|
||||
builder.Services.AddScoped<UmbracoHelper>();
|
||||
builder.Services.AddScoped<IBackOfficeSecurity, BackOfficeSecurity>();
|
||||
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Tests.Integration.TestServerTest;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Integration.Umbraco.Core
|
||||
{
|
||||
[TestFixture]
|
||||
public class PublishedContentQueryAccessorTests : UmbracoTestServerTestBase
|
||||
{
|
||||
[Test]
|
||||
public async Task PublishedContentQueryAccessor_WithRequestScope_WillProvideQuery()
|
||||
{
|
||||
HttpResponseMessage result = await Client.GetAsync("/demo-published-content-query-accessor");
|
||||
Assert.AreEqual(HttpStatusCode.OK, result.StatusCode);
|
||||
}
|
||||
}
|
||||
|
||||
public class PublishedContentQueryAccessorTestController : Controller
|
||||
{
|
||||
private readonly IPublishedContentQueryAccessor _accessor;
|
||||
|
||||
public PublishedContentQueryAccessorTestController(IPublishedContentQueryAccessor accessor)
|
||||
{
|
||||
_accessor = accessor;
|
||||
}
|
||||
|
||||
[HttpGet("demo-published-content-query-accessor")]
|
||||
public IActionResult Test()
|
||||
{
|
||||
var success = _accessor.TryGetValue(out IPublishedContentQuery query);
|
||||
|
||||
if (!success || query == null)
|
||||
{
|
||||
throw new ApplicationException("It doesn't work");
|
||||
}
|
||||
|
||||
return Ok();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user