Skip to content

Combine the contents of the views dll in to the app as part of hot reload / source generator effort #29862

Closed

Description

@pranavkm

Related to Hot Reload for ASP.NET Core

Summary

Razor views and Razor Pages currently compile to a separate assembly (MyApp.Views.dll). As part of net6, we could consider compiling it in to the app's assembly.

Motivation and goals

The decision to compile Razor files into a separate assembly had two primary motivators:

  • When build time compilation of Razor files was first introduced as part of 2.1, runtime compilation was an implicit part of the ASP.NET Core framework. It was an explicit goal to keep the behavior of build and runtime compiled Razor files identical. We did not want issues to crop up in production just because build time compiled views were being runtime compiled for some reason. Compiling views in to the app assembly posed a problem here - build time compiled views would have different behavior (predictable assembly identity, access to internal types in the app and all it's IVTs etc) compared to runtime compiled views.

  • There was also the technical challenge. Compiling razor files in to the app assembly requires a two-pass compile. Until Blazor in 3.0, we hadn't figured out how to do this.

In 3.x, runtime view compilation was relegated to being an opt-in primarily dev-time feature. With hot reload / EnC, we have an alternate model that gives us the same results as runtime compilation. What does this look like?

  • All Razor files - *.razor and *.cshtml files are compiled in to the app's main dll.
  • We rely on hot reload to drive dev time scenarios for all compilable files in an ASP.NET Core app. This means we get a consistent set of gestures and experiences when working with .cs, .razor, and .cshtml files when it comes to hot reload.
  • Users may continue to use the runtime compilation package, but we no longer guarantee that a build time compiled view would compile at runtime (consider a view that references a type that's internal to the app assembly, this would no longer compile with runtime compilation)

Q & A

  • Why can't we continue to compile views in a separate assembly and do a hot reload?

A few reasons come to mind:
- Hot Reload / EnC in VS relies on what files appear in the Roslyn workspace. Razor is problematic, our tooling adds design time code-generation to the workspace which isn't what you need to run. EnC is going to explicitly be made aware of this design time code-generation and will know how to swap it out with the correct runtime code. The design time for .cshtml files appear in the Roslyn workspace, so VS thinks your .cshtml file are part of the current project's assembly. Adding more complexity here is very likely going to get us push back. Since we're solving for .razor, we could already piggy-back .cshtml files on it.

  • With source generators, doing a 2-phase compile is cheap (it's all in memory). Consequently doing it when a project has no razor files shouldn't burden your build time. On the other hand, removing the extra compilation required to produce a .Views.dll would benefit build times.

  • Having an extra assembly, that nothing else in the SDK is aware of, but is required to run your app poses issues with linking, single file exe etc. We can solve that problem with this.

  • Does this mean I can address views or Razor Pages by type the same way as Razor components?

At this point no. Views and Razor Pages are addressed by paths. We can scromble[1] their names enough that you would not be able to reference it from other types.

  • Can I continue using runtime compilation in this new world?

Yes. None of the current scenarios are going to be broken.

In scope

  • Compile Razor (.cshtml) files in to the app's assembly.
  • Compiling MVC apps no longer produces an additional .Views.dll
  • .cshtml files are marked as reloadable types to have maximum EnC
  • Remove runtime compilation option from 6.0 project templates
  • Already compiled apps and libraries with a .views.dll continue working

Out of scope

  • While nearly all the work is primarily in the SDK, we are going to limit this to net6.0 (and newer) targeting apps.
  • Having a view in a separate assembly enabled a few interesting scenarios - being able to associate multiple Views.dll with an assembly (IdentityUI did this), turning on compilation only for build but not for publish. These scenarios are going to no longer be supported.
  • Runtime compilation will no longer be isometric with build time compilation.
  • Support for non-C# projects. This is no different from the experience you get with the SDK and build time compilation today.

Risks / unknowns

  • Hot reload has to have a comparable experience to runtime compilation. With the latter, no edits to cshtml files were considered rude.
  • Impact on tooling.
  • Impact on apps that rely on views being in a separate assembly.

[1] https://i.redd.it/u3lwvgqof5py.jpg

Activity

  1. added
    design-proposalThis issue represents a design proposal for a different issue, linked in the description
    on Feb 2, 2021
  2. added this to the Next sprint planning milestone on Feb 2, 2021
  3. added
    area-mvcIncludes: MVC, Actions and Controllers, Localization, CORS, most templates
    on Feb 3, 2021
  4. DamianEdwards commented on Feb 10, 2021

    @DamianEdwards
    Member

    The concept of "reloadable types" as a generic feature is currently out of scope for the Hot Reload effort in .NET 6.0. As such, we may need to implement reloading of new view types in the web workload specifically rather than relying on something central.

    @pranavkm do you have a rough idea of how we might approach that, given the move to source generators and the assumption of an IPC channel to the process to notify of changes?

  5. self-assigned this
    on Feb 16, 2021
  6. added
    enhancementThis issue represents an ask for new feature or an enhancement to an existing one
    and removed on Mar 11, 2021
  7. ghost closed this as completedin #31039on Mar 19, 2021
  8. added
    DoneThis issue has been fixed
    and removed on Mar 19, 2021
  9. ghost locked as resolved and limited conversation to collaborators on Apr 18, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

DoneThis issue has been fixedarea-mvcIncludes: MVC, Actions and Controllers, Localization, CORS, most templatesdesign-proposalThis issue represents a design proposal for a different issue, linked in the descriptionenhancementThis issue represents an ask for new feature or an enhancement to an existing onefeature-source-generators

Type

No type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions