Compartilhar controladores, exibições, Razor Pages e muito mais com Partes do Aplicativo

De Rick Anderson

Exibir ou baixar código de exemplo (como baixar)

Uma Parte do Aplicativo é uma abstração sobre os recursos de um aplicativo. As Partes do Aplicativo permitem que ASP.NET Core descubra controladores, exiba componentes, auxiliares de marca, Razor Páginas, fontes de compilação do Razor e muito mais. AssemblyPart é uma parte do aplicativo. AssemblyPart encapsula uma referência de assembly e expõe tipos e referências de compilação.

Provedores de recursos funcionam com as partes do aplicativo para preencher os recursos de um aplicativo do ASP.NET Core. O caso de uso principal das partes do aplicativo é configurar seu aplicativo para descobrir (ou evitar o carregamento) recursos de ASP.NET Core de um assembly. Por exemplo, talvez você queira compartilhar funcionalidades comuns entre vários aplicativos. Usando Partes do Aplicativo, você pode compartilhar um assembly (DLL) que contém controladores, exibições, Razor Pages, fontes de compilação de Razor, Auxiliares de Marca e muito mais com vários aplicativos. O compartilhamento de um assembly é preferencial para duplicar o código em vários projetos.

Aplicativos ASP.NET Core carregam recursos de ApplicationPart. A classe AssemblyPart representa uma parte de aplicativo que é apoiada por um assembly.

Carregar recursos de ASP.NET Core

Use as classes Microsoft.AspNetCore.Mvc.ApplicationParts e AssemblyPart para descobrir e carregar recursos de ASP.NET Core (controladores, componentes de exibição etc.). O ApplicationPartManager acompanha as partes do aplicativo e os provedores de recursos disponíveis. ApplicationPartManager é configurado em Startup.ConfigureServices:

// Requires using System.Reflection;
public void ConfigureServices(IServiceCollection services)
{
    var assembly = typeof(MySharedController).Assembly;
    services.AddControllersWithViews()
        .AddApplicationPart(assembly)
        .AddRazorRuntimeCompilation();

    services.Configure<MvcRazorRuntimeCompilationOptions>(options => 
    { options.FileProviders.Add(new EmbeddedFileProvider(assembly)); });
}

O código a seguir fornece uma abordagem alternativa para configurar ApplicationPartManager usando AssemblyPart:

// Requires using System.Reflection;
// Requires using Microsoft.AspNetCore.Mvc.ApplicationParts;
public void ConfigureServices(IServiceCollection services)
{
    var assembly = typeof(MySharedController).Assembly;
    // This creates an AssemblyPart, but does not create any related parts for items such as views.
    var part = new AssemblyPart(assembly);
    services.AddControllersWithViews()
        .ConfigureApplicationPartManager(apm => apm.ApplicationParts.Add(part));
}

Os dois exemplos de código anteriores carregam o SharedController de um assembly. O SharedController não está no projeto do aplicativo. Consulte o download de exemplo da solução WebAppParts.

Incluir exibições

Use uma Razor biblioteca de classes para incluir exibições no assembly.

Impedir o carregamento de recursos

As partes do aplicativo podem ser usadas para evitar o carregamento de recursos em um assembly ou local específico. Adicione ou remova membros da coleção Microsoft.AspNetCore.Mvc.ApplicationParts para ocultar ou disponibilizar recursos. A ordem das entradas na coleção ApplicationParts não é importante. Configure totalmente o ApplicationPartManager antes de usá-lo para configurar serviços no contêiner. Por exemplo, configure ApplicationPartManager antes de invocar AddControllersAsServices. Chame Remove na coleção ApplicationParts para remover um recurso.

O ApplicationPartManager inclui partes para:

  • O assembly do aplicativo e os assemblies dependentes.
  • Microsoft.AspNetCore.Mvc.ApplicationParts.CompiledRazorAssemblyPart
  • Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation
  • Microsoft.AspNetCore.Mvc.TagHelpers.
  • Microsoft.AspNetCore.Mvc.Razor.

Provedores de recursos

Os Provedores de recursos de aplicativo examinam as partes do aplicativo e fornece recursos para essas partes. Há provedores de recursos internos para os seguintes recursos de ASP.NET Core:

Provedores de recursos herdam de IApplicationFeatureProvider<TFeature>, em que T é o tipo do recurso. Os provedores de recursos podem ser implementados para qualquer um dos tipos de recursos listados anteriormente. A ordem dos provedores de recursos no ApplicationPartManager.FeatureProviders pode afetar o comportamento do tempo de execução. Posteriormente os provedores adicionados podem reagir a ações executadas por provedores adicionados anteriormente.

Exibir recursos disponíveis

Os recursos disponíveis para um aplicativo podem ser enumerados solicitando um ApplicationPartManager por meio de injeção de dependência:

using AppPartsSample.ViewModels;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ApplicationParts;
using Microsoft.AspNetCore.Mvc.Controllers;
using System.Linq;
using Microsoft.AspNetCore.Mvc.Razor.Compilation;
using Microsoft.AspNetCore.Mvc.Razor.TagHelpers;
using Microsoft.AspNetCore.Mvc.ViewComponents;

namespace AppPartsSample.Controllers
{
    public class FeaturesController : Controller
    {
        private readonly ApplicationPartManager _partManager;

        public FeaturesController(ApplicationPartManager partManager)
        {
            _partManager = partManager;
        }

        public IActionResult Index()
        {
            var viewModel = new FeaturesViewModel();

            var controllerFeature = new ControllerFeature();
            _partManager.PopulateFeature(controllerFeature);
            viewModel.Controllers = controllerFeature.Controllers.ToList();

            var tagHelperFeature = new TagHelperFeature();
            _partManager.PopulateFeature(tagHelperFeature);
            viewModel.TagHelpers = tagHelperFeature.TagHelpers.ToList();

            var viewComponentFeature = new ViewComponentFeature();
            _partManager.PopulateFeature(viewComponentFeature);
            viewModel.ViewComponents = viewComponentFeature.ViewComponents.ToList();

            return View(viewModel);
        }
    }
}

O exemplo de download usa o código anterior para exibir os recursos do aplicativo:

Controllers:
    - FeaturesController
    - HomeController
    - HelloController
    - GenericController`1
    - GenericController`1
Tag Helpers:
    - PrerenderTagHelper
    - AnchorTagHelper
    - CacheTagHelper
    - DistributedCacheTagHelper
    - EnvironmentTagHelper
    - Additional Tag Helpers omitted for brevity.
View Components:
    - SampleViewComponent

Descoberta em partes do aplicativo

Erros HTTP 404 não são incomuns ao desenvolver com partes do aplicativo. Normalmente esses erros são causados por falta de um requisito essencial para como as partes de aplicativos são descobertas. Se o aplicativo retornar um erro HTTP 404, verifique se os seguintes requisitos foram atendidos:

  • A configuração applicationName precisa ser definida como o assembly raiz usado para descoberta. O assembly raiz usado para descoberta normalmente é o assembly do ponto de entrada.
  • O assembly raiz precisa ter uma referência às partes usadas para descoberta. A referência pode ser direta ou transitiva.
  • O assembly raiz precisa fazer referência ao SDK da Web. A estrutura tem uma lógica que carimba atributos no assembly raiz que são usados para descoberta.

De Rick Anderson

Exibir ou baixar código de exemplo (como baixar)

Uma Parte do Aplicativo é uma abstração sobre os recursos de um aplicativo. As Partes do Aplicativo permitem que ASP.NET Core descubra controladores, exiba componentes, auxiliares de marca, Razor Páginas, fontes de compilação do Razor e muito mais. AssemblyPart é uma parte do aplicativo. AssemblyPart encapsula uma referência de assembly e expõe tipos e referências de compilação.

Provedores de recursos funcionam com as partes do aplicativo para preencher os recursos de um aplicativo do ASP.NET Core. O caso de uso principal das partes do aplicativo é configurar seu aplicativo para descobrir (ou evitar o carregamento) recursos de ASP.NET Core de um assembly. Por exemplo, talvez você queira compartilhar funcionalidades comuns entre vários aplicativos. Usando Partes do Aplicativo, você pode compartilhar um assembly (DLL) que contém controladores, exibições, Razor Pages, fontes de compilação de Razor, Auxiliares de Marca e muito mais com vários aplicativos. O compartilhamento de um assembly é preferencial para duplicar o código em vários projetos.

Aplicativos ASP.NET Core carregam recursos de ApplicationPart. A classe AssemblyPart representa uma parte de aplicativo que é apoiada por um assembly.

Carregar recursos de ASP.NET Core

Use as classes ApplicationPart e AssemblyPart para descobrir e carregar recursos de ASP.NET Core (controladores, componentes de exibição etc.). O ApplicationPartManager acompanha as partes do aplicativo e os provedores de recursos disponíveis. ApplicationPartManager é configurado em Startup.ConfigureServices:

public void ConfigureServices(IServiceCollection services)
{
    // Requires using System.Reflection;
    var assembly = typeof(MySharedController).GetTypeInfo().Assembly;
    services.AddMvc()
        .AddApplicationPart(assembly)
        .SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}

O código a seguir fornece uma abordagem alternativa para configurar ApplicationPartManager usando AssemblyPart:

public void ConfigureServices(IServiceCollection services)
{
    // Requires using System.Reflection;
    // Requires using Microsoft.AspNetCore.Mvc.ApplicationParts;
    var assembly = typeof(MySharedController).GetTypeInfo().Assembly;
    var part = new AssemblyPart(assembly);
    services.AddMvc()
        .ConfigureApplicationPartManager(apm => apm.ApplicationParts.Add(part))
        .SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}

Os dois exemplos de código anteriores carregam o SharedController de um assembly. O SharedController não está no projeto do aplicativo. Consulte o download de exemplo da solução WebAppParts.

Incluir exibições

Use uma Razor biblioteca de classes para incluir exibições no assembly.

Impedir o carregamento de recursos

As partes do aplicativo podem ser usadas para evitar o carregamento de recursos em um assembly ou local específico. Adicione ou remova membros da coleção Microsoft.AspNetCore.Mvc.ApplicationParts para ocultar ou disponibilizar recursos. A ordem das entradas na coleção ApplicationParts não é importante. Configure totalmente o ApplicationPartManager antes de usá-lo para configurar serviços no contêiner. Por exemplo, configure ApplicationPartManager antes de invocar AddControllersAsServices. Chame Remove na coleção ApplicationParts para remover um recurso.

O código a seguir usa Microsoft.AspNetCore.Mvc.ApplicationParts para remover MyDependentLibrary do aplicativo:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc()
            .SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
            .ConfigureApplicationPartManager(apm =>
            {
                var dependentLibrary = apm.ApplicationParts
                    .FirstOrDefault(part => part.Name == "MyDependentLibrary");

                if (dependentLibrary != null)
                {
                    apm.ApplicationParts.Remove(dependentLibrary);
                }
            });
}

O ApplicationPartManager inclui partes para:

  • O assembly do aplicativo e os assemblies dependentes.
  • Microsoft.AspNetCore.Mvc.TagHelpers.
  • Microsoft.AspNetCore.Mvc.Razor.

Provedores de recursos de aplicativo

Os Provedores de recursos de aplicativo examinam as partes do aplicativo e fornece recursos para essas partes. Há provedores de recursos internos para os seguintes recursos de ASP.NET Core:

Provedores de recursos herdam de IApplicationFeatureProvider<TFeature>, em que T é o tipo do recurso. Os provedores de recursos podem ser implementados para qualquer um dos tipos de recursos listados anteriormente. A ordem dos provedores de recursos no ApplicationPartManager.FeatureProviders pode afetar o comportamento do tempo de execução. Posteriormente os provedores adicionados podem reagir a ações executadas por provedores adicionados anteriormente.

Exibir recursos disponíveis

Os recursos disponíveis para um aplicativo podem ser enumerados solicitando um ApplicationPartManager por meio de injeção de dependência:

using AppPartsSample.ViewModels;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ApplicationParts;
using Microsoft.AspNetCore.Mvc.Controllers;
using System.Linq;
using Microsoft.AspNetCore.Mvc.Razor.Compilation;
using Microsoft.AspNetCore.Mvc.Razor.TagHelpers;
using Microsoft.AspNetCore.Mvc.ViewComponents;

namespace AppPartsSample.Controllers
{
    public class FeaturesController : Controller
    {
        private readonly ApplicationPartManager _partManager;

        public FeaturesController(ApplicationPartManager partManager)
        {
            _partManager = partManager;
        }

        public IActionResult Index()
        {
            var viewModel = new FeaturesViewModel();

            var controllerFeature = new ControllerFeature();
            _partManager.PopulateFeature(controllerFeature);
            viewModel.Controllers = controllerFeature.Controllers.ToList();

            var tagHelperFeature = new TagHelperFeature();
            _partManager.PopulateFeature(tagHelperFeature);
            viewModel.TagHelpers = tagHelperFeature.TagHelpers.ToList();

            var viewComponentFeature = new ViewComponentFeature();
            _partManager.PopulateFeature(viewComponentFeature);
            viewModel.ViewComponents = viewComponentFeature.ViewComponents.ToList();

            return View(viewModel);
        }
    }
}

O exemplo de download usa o código anterior para exibir os recursos do aplicativo:

Controllers:
    - FeaturesController
    - HomeController
    - HelloController
    - GenericController`1
    - GenericController`1
Tag Helpers:
    - PrerenderTagHelper
    - AnchorTagHelper
    - CacheTagHelper
    - DistributedCacheTagHelper
    - EnvironmentTagHelper
    - Additional Tag Helpers omitted for brevity.
View Components:
    - SampleViewComponent

Descoberta em partes do aplicativo

Erros HTTP 404 não são incomuns ao desenvolver com partes do aplicativo. Normalmente esses erros são causados por falta de um requisito essencial para como as partes de aplicativos são descobertas. Se o aplicativo retornar um erro HTTP 404, verifique se os seguintes requisitos foram atendidos:

  • A configuração applicationName precisa ser definida como o assembly raiz usado para descoberta. O assembly raiz usado para descoberta normalmente é o assembly do ponto de entrada.
  • O assembly raiz precisa ter uma referência às partes usadas para descoberta. A referência pode ser direta ou transitiva.
  • O assembly raiz precisa fazer referência ao SDK da Web.
    • A estrutura ASP.NET Core tem uma lógica de build personalizada que carimba atributos no assembly raiz que são usados para descoberta.