Skip to content

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

Closed
@pranavkm

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

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