Where is .AddDbContext method? - asp.net-core

Everywhere it's said to call services.AddDbContext<> method but it is not recognized inside the ConfigureServices(IServiceCollection services) method.
What am I doing wrong?

You have to reference the correct package first, which depends on the EF Core provider you want to use.
Microsoft.EntityFrameworkCore.SqlServer for SQL Server, Microsoft.EntityFrameworkCore.Sqlite for SQLite and Microsoft.EntityFrameworkCore.InMemory for in memory (only for testing).
These are the official out-of-the-box providers. There are also 3rd party providers for PostgreSQL, MySQL, etc. The documentation providers a list of available 3rd party providers here.
Also depending on the provider you may also need to declare a certain namespace. The built-in providers are declared in Microsoft.Extension.DependencyInjection namespace so you need to add a using Microsoft.Extension.DependencyInjection; to the top of your Startup.cs.
Other providers (Oracle's MySQL provider for example) uses MySQL.Data.EntityFrameworkCore.Extensions namespace, so you need to define this using using MySQL.Data.EntityFrameworkCore.Extensions;

Note when actually writing the using you only have to reference Microsoft.EntityFrameworkCore omitting the specific package name. Providing it seems to throw an error.

Related

Using ActivatorUtilities.CreateInstance<Service> in razor components

ActivatorUtilities.CreateInstance requires a service provider in order to properly resolve. The service provider is whats being used when resolving injected properties in razor components/pages.
If I want to make use of this in my razor components/pages, do I need to also inject a service provider or a means to get a service provider like through iservicescopefactory? Seems somewhat repetitive but not sure if there's an alternative to this approach.
Background: What I'd like to do is use this utility function to create services that require state values to properly instantiate (values not available when initially constructing the service collection in program.cs) while also leveraging the services already available in my service provider. Not sure if it makes sense to use this to continue making use of di or to just manually construct the class on the fly using the state values

Should I use IEmailSender?

I'm using AspNetCore.Identity at my project, so I write a EmailSender class that implements this interface.
Everything is working fine.
But this description about IEmailSender took my attention:
Microsoft.AspNetCore.Identity.UI.Services.IEmailSender
This API supports the ASP.NET Core Identity default UI infraestructure and is not intended to be used directly from your code. This API may change or be removed in future releases
If it isn't intended to be used directly in my code, what should I use?
My application also send emails in other parts, not only for Identity.
I don't think you need to use IEmailSender. In fact, based on my experience, to some degrees I think you shouldn't use it:
In .NET 5.0, IEmailSender is in the package ASP.NET Core Identity.UI, with the default implementation injected in DI that doesn't do anything. It's perfectly fine if you want to use the default UI provided by the framework. But if you don't like to use those default pages and just want to use the core of the Identity framework, including the whole package just to get IEmailSender interface seems overkill to me. Not to mention there is an annoying bug when using Identity UI at this moment.
It doesn't add any value. I would have been persuaded if the framework could automatically scan my concrete implementation and use that instead to send out emails. But that's not the case. You would have to inject your email sender through DI by services.AddSingleton<>() yourself and use it via constructor injection where you want to send emails.
IEmailSender.SendEmailAsync(string email, string subject, string htmlMessage) method is pretty basic. Most of the time you even would have to create your own razor library to generate the HTML message yourself. In my case (using SendGrid v9.22 with dynamic template), I would need to not only pass the HTML message, but also the template data (for setting the placeholder in my SendGrid template via msg.SetTemplateData()). The basic SendEmailAsync() just doesn't have extra parameters for me to send additional data when sending the email.
Conclusion:
If you see yourself that you won't switch to email provider for a project, you might as well just create a concrete email sender that fits you well, and inject that into DI directly.
If you see there might be a time when your project will switch email provider, having a basic and simple interface, like IEmailSender, makes sense.
You definitely should, as the IEmailSender is the best available option offered by the framework to send email messages, especially if you have to deal with ASP.NET Identity stuff (account confirmation, password recovery and so on).
However, in order to use it properly, you should implement it using one of the many third-party services (and their corresponding .NET NuGet packages), as suggested in this official post.
If you need further instruction to setup these email sender provider, you can take a look at these implementation guides that I wrote on my blog (DISCLAIMER: I'm not affiliated with any of them):
.NET Core General Purpose SMTP implementation using MailKit
.NET Core IEmailSender implementation using Twilio SendGrid API
.NET Core IEmailSender implementation using SendInBlue API
The fact that the API could get removed in the future shouldn't bother you at all, since all of these third-party packages have their own API: you'll be able to use them even without the IEmailSender interface (as a matter of fact, you already can).

Adding service for EF, AddDbContext or AddEntityFramework

Is there a difference between services.AddDbContext and services.AddEntityFramework().AddDbContext? They booth looks to be valid under core-1.0.0.
Choice A
services.AddDbContext<DbContext>(options => options.UseSqlServer(connection));
Choice B
services.AddEntityFramework()
.AddDbContext<DbContext>(options =>
options.UseSqlServer(connection));
Also noticed that .AddSqlServer() looks to be gone. Last time I did some work on core was RC2 and I see that a lot has been cleaned/renamed/simplified, I guess that's nice.
I'm quoting: You only need to use this functionality (AddEntityFramework) when you want Entity Framework to resolve the services it uses from an external IServiceProvider.
If you are not using an external IServiceProvider, Entity Framework will take care of creating the services it requires.
See: https://github.com/aspnet/EntityFramework/blob/dev/src/Microsoft.EntityFrameworkCore/Infrastructure/EntityFrameworkServiceCollectionExtensions.cs
I'm quoting: Intentionally in this namespace since this is for use by other relational providers rather than by top-level app developers.
See: https://github.com/aspnet/EntityFramework/blob/94138e66a56693395e5e323a8d4b666bbcb07bf7/src/Microsoft.EntityFrameworkCore/Infrastructure/EntityFrameworkServiceCollectionExtensions.cs

Replacement Implementation for Provider Model in ASP.NET 5

I have existing code that uses System.Configuration.Provider namespace for provider collections to plugin various implementations of interfaces, where multiple implementations exist in the collection and are selected by name according to various logic.
This namespace is not available in .net core, so I'm looking for advice on how to implement a replacement solution that will work with .net core framework.
I know that if I was just trying to plugin one implementation, I could do it by dependency injection. But I'm looking for a way to have multiple implementations available to choose based on name.
My current implementation with provider model populates the provider collection from a folder where you can drop in xml files that declare the type of the actual implementations, so new implementations of the provider can be loaded from an assembly by just adding another file to the folder. I'd like to keep the logic as similar as possible to that but I'm open to json files rather than xml.
I am thinking I could load up a collection of implementations of the interface from json files in Startup and use dependency injection to provide the collection where needed or perhaps an interface that can get the collection would be lighter weight and allow getting them when they are needed rather than at startup.
Is that the right approach? Anyone have better ideas or done something similar?
This is done more generically than using an abstract base class like ProviderBase in the new framework. You can register multiple of the same service with the DI framework and get them all either simply by asking for an IEnumerable<> of the type you register them as or using the GetRequiredServices<> extension method. Once you get your services, however, you'll need some other way of distinguishing them, such as a property indicating a unique name, which is the pattern the ASP.Net team has been following.
You can see an example in the Identity framework v3 with the Token Providers.
IUserTokenProvider<T>, the "provider"
UserManager, which consumes the token managers

When I use WsdlImporter I got different data then with Add Web Reference

I have to connect to the service provided by the third party client. The issue is to do that dynamically. When I generate proxy on a static way with Add web reference everything is OK. With usage of WsdlImporter and CodeDom I get some strange generated classes (for proxy client per instance).
Then I saw in case of Add Service Reference I got the same values as with WsdlImporter. My conclusion WsdlImporter is used by svcutil.exe.
Does someone knows what is here so different ?
Service is using SOAP1.1
They're just two different tools. svcutil.exe actually uses WsdlImporter under the covers (which is why the two outputs are the same). Add Web Reference uses the same classes as the tool wsdl.exe (I don't know which class they use internally, but you can use a tool such as ILSpy or reflector to see what wsdl.exe uses.
"Add Web Reference" is part of the legacy ASMX support, not part of WCF. Don't use it if you have a choice.
The solution of this problem is to use ServiceDescriptionImporter. This importer is working as wsdl.exe .
Additionally, XSD schemes have to be imported (also take care on nested schemas). Great sample for this is on the following :
http://forums.asp.net/post/1740748.aspx
Thank you all, it works now