dotnet / aspire

An opinionated, cloud ready stack for building observable, production ready, distributed applications in .NET
https://learn.microsoft.com/dotnet/aspire
MIT License
3.36k stars 347 forks source link

SMTP hosting resources types and application libraries #4063

Open mitchdenny opened 2 months ago

mitchdenny commented 2 months ago

In the following tutorial we showed how to build a hosting component for an open-source dev-time SMTP server to help people debug code that needs to use an SMTP server:

https://learn.microsoft.com/en-us/dotnet/aspire/extensibility/custom-resources?tabs=windows

For the purposes of the tutorial we just added a singleton of System.Net.Mail.SmtpClient to the DI container. There has been some interest from the developer community around having a SMTP component inside the .NET Aspire codebase. We should explore that.

It probably makes sense to use the System.Net.Mail.SmtpClient so this is probably more around creating the DI registration mechanics. We probably wouldn't be able to do anything like automatic retries, service discovery, or anything like that (unless someone wanted to take on that work within runtime as well).

I'm thinking that we should have hosting components for MailDev and Mailpit (local dev focused options). But we could potentially have hosting packages for some of the other e-mail service providers.

AndrewBabbitt97 commented 2 months ago

Was actually just thinking about this as well, here's another option aside from maildev: https://github.com/dbck/docker-mailtrap

Uses SMTP + IMAP + Roundcube

AndrewBabbitt97 commented 2 months ago

It may also make a lot of sense to have a component for MailKit as it is probably the biggest .NET Emailing library covering SMTP, IMAP, and POP: https://github.com/jstedfast/MailKit

Note: MailKit has also been working on metrics / telemetry support

mitchdenny commented 1 month ago

I'd be interested in @jstedfast's perspective on this. For Aspire we have a model for adding Aspire-specific APIs to glue in various OSS libraries (for example we could have Aspire.MailKit) which helps wireup MailKit's awesomeness into the various telemetry plumbing we have in Aspire.

It would probably pretty neatly solve the client-side API problem. We'd still need hosting components of which there could be many flavors. ideally we could agree on a connection string format.

jstedfast commented 1 month ago

For a connection string format, starting with something like An SMTP URL Interface might be a good starting point.

The IMAP URL syntax was finalized (unlike the SMTP URL syntax link above) and so it may be worth looking it over (in case there are any differences worth considering) and extracting the parts that make sense for SMTP (like specifying authentication mechanisms). Obviously, most of it will be meaningless for SMTP, though.

There's also the POP3 URL scheme: https://datatracker.ietf.org/doc/html/rfc2384

I haven't had much time to look these RFCs over yet, but they've been on my radar for a while now. Largely I haven't bothered reading them in much depth because I've been focused on the implementation of the clients rather than the perspective of a service for which a URL syntax for specifying a resource makes more practical sense.

mitchdenny commented 1 month ago

Yeah, I think building from smtp://host[:port] to the various auth mechanisms mentioned in the draft make sense.

mitchdenny commented 1 month ago

Once the format of the connection string is established them being able to plug and play different mail servers and clients becomes a heck of a lot easier.