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).
Related
I want to use a SOAP web service prepared by another team, used internally in my new REST API prepared in ASP.NET Core. My web service client code was scaffolded with WCF Web Service Reference Provider Tool. I cleaned up code (e.g. I changed property and method names) according to my team's naming convention.
When I send requests by my new REST API, I received WrongInputException. I checked all the parameters from an example request, all of them are in the same place in my C# code consuming scaffolded client.
I don't know what message exactly is sent by my new REST API.
In my case, the main cause of the described behavior and WrongInputException was premature refactoring. I changed the names of properties in the web service client without knowledge of the consequences.
E.g. if the element in the request body is objectRefNum, then I cannot simply change the related property in the scaffolded service reference class, because - without extra configuration - that name is copied with the same letter case to the request body of the SOAP envelope. The SOAP envelope should be encoded in the case-sensitive mode.
To trace the raw request body send by my new REST API in ASP.NET Core, I followed instructions from this excellent answer.
(Note, BTW, that kind of error (applying inappropriate letter case) could be handled by IDE, at least as a warning, but it is not, so: we need to be careful when we make refactoring, even if we have unit tests covering all the paths, and even if we use semantic renaming supported by IDE.)
Looking at the code for AuthenticationServiceCollectionExtensions.AddAuthentication() vs AuthenticationCoreServiceCollectionExtensions.AddAuthenticationCore(), it looks like AddAuthentication implicitly calls AddAuthenticationCore, adds some other goodies, and then returns a new instance of AuthenticationBuilder instead of just returning IServiceCollection.
Am I understanding the code correctly? If so, are there generally any reasons to call AddAuthenticationCore instead of AddAuthentication outside of writing your own extension?
It seems to be a typical pattern in ASP.NET Core: the Add[xxx]Core methods add the bare minimum to enable a feature, but without any bells and whistles. It's also probably used to make unit testing the core features easier.
You can make a parallel with the AddMvc vs AddMvcCore methods. There's a question that asks Should I use AddMvc or AddMvcCore for ASP.NET Core MVC development?, and the gist is that it allows for fine-grained control on what middleware you want to use.
To answer your question: for a typical user, there's probably no reason to use AddAuthenticationCore.
Actually there is a reason. Currently AddAuthentication() also adds data protection services, which you may not need - for example if you are writing your own Authentication Scheme. So instead you can do this:
services.AddAuthenticationCore(o => {
o.DefaultScheme = "My Custom Scheme";
});
services.AddWebEncoders();
services.AddSingleton<ISystemClock, SystemClock>();
var authBuilder = new AuthenticationBuilder(services);
however I fully expect this to break in future versions of asp.net core as it's undocumented and a bit of a hack.
I am using ASP.Net core and I have a requirement to access a specific HTTP Header in a business logic class (not a controller or action).
To provide a full picture of the configuration here, I have a custom ASP.Net Core Middleware which based on some logic will add a value into a custom HTTP Header, it is the value from this header that I need to access in the business logic class.
Currently the way that I achieve this is to inject an HttpContextAccessor, using the following DI registration.
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
In the class which requires access to the HTTP Headers I then request an IHttpContextAccessor using constructor injection and use this to access the relevant HTTP Header.
Doing the above works fine and gives me the results that I require, looking around various articles on the Internet however the general consensus appears to be to avoid using HttpContext.Current in ASP.Net Core.
If the above is the case, is there a better way for my business logic class to access the value that my custom middleware is inserting into a custom HTTP Header?
I should be clear, whilst at present the middleware is storing the required value in a HTTP Header for use by the business logic class, I am open to other methods of the middleware making the required value available to the business logic class if there is a better approach.
Any questions or clarifications, please let me know.
There is no HttpContext.Current in ASP.Net Core, so it's easy to avoid using it. You would have to implement your own extension method if you wanted it, but the general feeling in the .Net Core community is that it's much better to use IHttpContextAccessor.
In earlier versions of .Net Core an implementation of IHttpContextAccessor was auto registered in the DI container. In more current version you have to register it yourself with the line of code you mentioned:
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
Injecting IHttpContext into your method that needs access to the headers is a workable approach. Or if you like you could use a helper method that places a copy of the headers in a simpler structure and then pass that object in to your class since it doesn't really need access to the full HttpContext.
I'm creating a new application in Zend Framework 3 and i have a question about a design pattern
Without entering in much details this application will have several Services, as in, will be connecting to external APIs and even in multiple databases, the workflow is also very complex, a single will action can have multiple flows depending on several external information (wich user logged in, configs, etc).
I know about dependency injections and Zend Framework 3 Service Manager, however i am worried about instanciating sereval services when the flow will actually use only a few of them in certain cases, also we will have services depending on other services aswell, for this, i was thinking about using singletons.
Is singleton really a solution here? I was looking a way to user singletons in Zend Framework 3 and haven't figured out a easy way since i can't find a way to user the Service Manager inside a service, as I can't retrive the instance of the Service Manager outside of the Factory system.
What is an easy way to implement singletons in Zend Framework 3?
Why use singletons?
You don't need to worry about too many services in your service manager since they are started only when you get them from the service manager.
Also don't use the service manager inside another class except a factory. In ZF3 it's removed from the controllers for a reason. One of them is testability. If all services are inject with a factory, you can easily write tests. Also if you read your code next year, you can easily see what dependencies are needed inside a class.
If you find there are too many services being injected inside a class which are not always needed you can:
Use the ProxyManager. This lazy loads a service but doesn't start it until a method is called.
Split the service: Move some parts from a service into a new service. e.g. You don't need to place everything in an UserService. You can also have an UserRegisterService, UserEmailService, UserAuthService and UserNotificationsService.
In stead of ZF3, you can also think about zend-expressive. Without getting into too much detail, it is a lightweight middleware framework. You can use middleware to detect what is needed for a request and route to the required action to process the request. Something like this can probably also done in ZF3 but maybe someone else can explain how to do it there.
I'd read it somewhere that whenever one needs to do data intensive work then Webapi could be used. Ex: autocomplete textbox where we get data from using ajax on key press.
Now someone told me that Webapi shouldn't be used within applications which are not externally accessed. Rather action should be used to the same work as it is capable of returning the data back in a similar fashion to webapi.
I'd like to know your suggestions over it.
Depends on how you look at it. If all you need is ajax-ification of your controller actions, then you really don't need Web-API. Your actions can return a JsonResult and it is very easy to consume that from your client side through an AJAX call.
Web-API makes it easy for you to expose you actions to external clients. It supports HTTP protocol and Json and XML payloads automatically, out of the box, without you writing the code for it. Now, there is nothing preventing you from consuming the same Web-API actions from your own internal clients in an AJAX manner.
So the answer to your question depends on your design. If you don't have external clients, then there is no string need for you to have Web-API. Your standard controller actions can do the job.