Prevent issues for those who wish use ServiceBasedControllerActivator.
Adds registration for CurrentUserController which has ambiguous constructors. Register our controllers so that issues are visible during dev/test.
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Umbraco.Cms.Core.Cache;
|
||||
using Umbraco.Cms.Core.DependencyInjection;
|
||||
@@ -54,7 +55,8 @@ namespace Umbraco.Extensions
|
||||
.AddCoreNotifications()
|
||||
.AddLogViewer()
|
||||
.AddExamine()
|
||||
.AddExamineIndexes();
|
||||
.AddExamineIndexes()
|
||||
.AddControllersWithAmbiguousConstructors();
|
||||
|
||||
public static IUmbracoBuilder AddUnattendedInstallInstallCreateUser(this IUmbracoBuilder builder)
|
||||
{
|
||||
@@ -119,5 +121,21 @@ namespace Umbraco.Extensions
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds explicit registrations for controllers with ambiguous constructors to prevent downstream issues for
|
||||
/// users who wish to use <see cref="Microsoft.AspNetCore.Mvc.Controllers.ServiceBasedControllerActivator"/>
|
||||
/// </summary>
|
||||
public static IUmbracoBuilder AddControllersWithAmbiguousConstructors(
|
||||
this IUmbracoBuilder builder)
|
||||
{
|
||||
builder.Services.TryAddTransient(sp =>
|
||||
{
|
||||
IUserDataService userDataService = sp.GetRequiredService<IUserDataService>();
|
||||
return ActivatorUtilities.CreateInstance<CurrentUserController>(sp, userDataService);
|
||||
});
|
||||
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Microsoft.AspNetCore.Mvc.Controllers;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||
using Umbraco.Cms.Core.Composing;
|
||||
using Umbraco.Cms.Core.DependencyInjection;
|
||||
|
||||
namespace Umbraco.Cms.Web.UI.Composers
|
||||
{
|
||||
/// <summary>
|
||||
/// Adds controllers to the service collection.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// Umbraco 9 out of the box, makes use of <see cref="DefaultControllerActivator"/> which doesn't resolve controller
|
||||
/// instances from the IOC container, instead it resolves the required dependencies of the controller and constructs an instance
|
||||
/// of the controller.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// Some users may wish to switch to <see cref="ServiceBasedControllerActivator"/> (perhaps to make use of interception/decoration).
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// This composer exists to help us detect ambiguous constructors in the CMS such that we do not cause unnecessary effort downstream.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// This Composer is not shipped by the Umbraco.Templates package.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public class ControllersAsServicesComposer : IComposer
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public void Compose(IUmbracoBuilder builder) => builder.Services
|
||||
.AddMvc()
|
||||
.AddControllersAsServicesWithoutChangingActivator();
|
||||
}
|
||||
|
||||
internal static class MvcBuilderExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// <see cref="MvcCoreMvcBuilderExtensions.AddControllersAsServices"/> but without the replacement of
|
||||
/// <see cref="DefaultControllerActivator"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// We don't need to opt in to <see cref="ServiceBasedControllerActivator"/> to ensure container validation
|
||||
/// passes.
|
||||
/// </remarks>
|
||||
public static IMvcBuilder AddControllersAsServicesWithoutChangingActivator(this IMvcBuilder builder)
|
||||
{
|
||||
var feature = new ControllerFeature();
|
||||
builder.PartManager.PopulateFeature(feature);
|
||||
|
||||
foreach (Type controller in feature.Controllers.Select(c => c.AsType()))
|
||||
{
|
||||
builder.Services.TryAddTransient(controller, controller);
|
||||
}
|
||||
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user