Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Blazor Scaffolding is broken due to regression #3131

Open
coderdnewbie opened this issue Dec 19, 2024 · 2 comments
Open

Blazor Scaffolding is broken due to regression #3131

coderdnewbie opened this issue Dec 19, 2024 · 2 comments

Comments

@coderdnewbie
Copy link

coderdnewbie commented Dec 19, 2024

I already reported this in dotnet/aspnetcore#59491, but have been asked to put it here instead.

The bug is this:

  1. I created a brand new Blazor App with Identity and Interactive Auto, using the Web App template.

  2. I added the movie.cs file from Microsoft learning https://www.youtube.com/watch?v=ZN-CcfEY3Z8 and added scaffolding.

  3. I did migrations and and update database using connected services

  4. Fixed some scaffolding errors. Tried to go to localhost movies page. Got the following Exception:

InvalidOperationException: Cannot provide a value for property 'DbFactory' on type 'BlazorAppId.Components.Pages.MoviePages.Index'. There is no registered service of type 'Microsoft.EntityFrameworkCore.IDbContextFactory`1[BlazorAppId.Data.ApplicationDbContext]'.

The fix in program.cs, is to change builder.Services.AddDbContext<...>to builder.Services.AddDbContextFactory<...>and then it works as expected.

The issue is that the scaffolding pages are injecting:

@Inject IDbContextFactory<BlazorAppId.Data.ApplicationDbContext> DbFactory

but the program.cs is set as builder.Services.AddDbContext<...>

This is a regression as this used to work in .Net 8.0.

The feedback was this:

I believe I see where things went sideways.

When you were scaffolding, you probably selected the existing dB context ... the one that Identity placed ... instead of creating a new context for the scaffolding operation. If you select the plus sign next to DbContext class to add a new one (e.g., with the Blazor movie dB tutorial, we recommend BlazorWebAppMovies.Data.BlazorWebAppMoviesContext), then it creates the context for the added Razor components with AddDbContextFactory ...

builder.Services.AddDbContextFactory(options =>
options.UseSqlServer(builder.Configuration.GetConnectionString("BlazorWebAppMoviesContext") ??
throw new InvalidOperationException("Connection string 'BlazorWebAppMoviesContext' not found.")));

... which is the one that the components will use ...

@Inject IDbContextFactory<BlazorWebAppMovies.Data.BlazorWebAppMoviesContext> DbFactory

It creates that in addition to the one that's already there for Identity ...

builder.Services.AddDbContext(options =>
options.UseSqlServer(connectionString));

Two things come to mind on addressing this ...

Given that Dan's YT tutorial (and the written tutorial) don't get into adding Identity, it doesn't surprise me that his scaffolding step doesn't broach the subject of what to do if you're creating the app with Identity. I don't think that he (or I for the written tutorial) necessarily need to make a change to these tutorial experiences. Adding Identity is out of scope for these tutorials.

However for the scaffolder, it does lead to a poor user experience if the dev is scaffolding the components and the tooling suggests the existing dB context and does nothing to indicate that using it is going to 💥 on them. Perhaps, the scaffolder can be programmed to suggest a new context, which will lead to getting one based on AddDbContextFactory. I agree with you that the scaffolder can probably address this situation.

I have closed dotnet/aspnetcore#59491 as advised by https://github.com/guardrex

@guardrex
Copy link

Thanks @coderdnewbie ... I'll keep an 👁 on this to see how it plays out. If devs hit this problem using the written tutorial, I can make an addition to the text of the tutorial, probably a NOTE, that tells devs to create a new dB context if they've created the app with Identity. Thus far, I'm going to wait and see what happens because creating that app with Identity is out of scope of the tutorial.

It dawned on me after we chatted this morning that we have a section on scaffolding QuickGrid in the QuickGrid article at ...

https://learn.microsoft.com/en-us/aspnet/core/blazor/components/quickgrid?view=aspnetcore-9.0&tabs=visual-studio#quickgrid-scaffolder

That's a great place to call this out for .NET 9, so I've opened dotnet/AspNetCore.Docs#34401. I'll place content there right now 🏃‍♂ and cross-link this issue so that I don't lose track of them fixing the scaffolder, probably for .NET 10.

@coderdnewbie
Copy link
Author

coderdnewbie commented Dec 20, 2024

No problems, I have seen youtube videos where @danroth27 does the following (which also breaks in the same way).

  1. Do the Movie.cs scaffolding demo without identity
  2. Demo adding identity manually

This was when @danroth27 was demoing that you can now add identity with an existing app.

Also https://learn.microsoft.com/en-us/aspnet/core/blazor/blazor-ef-core?view=aspnetcore-9.0 it says that the recommended approach is AddDbContextFactory:

The recommended approach to create a new [DbContext](https://learn.microsoft.com/en-us/dotnet/api/microsoft.entityframeworkcore.dbcontext) with dependencies is to use a factory. EF Core 5.0 or later provides a built-in factory for creating new contexts.

The following example configures [SQLite](https://www.sqlite.org/index.html) and enables data logging. The code uses an extension method (AddDbContextFactory) to configure the database factory for DI and provide default options:

C#

Copy
builder.Services.AddDbContextFactory<ContactContext>(opt =>
    opt.UseSqlite($"Data Source={nameof(ContactContext.ContactsDb)}.db"));

The factory is injected into components and used to create new DbContext instances

If you need more evidence to convince, you can mention this, but the fact it throws the exception is the more serious matter.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants