Reputation: 83
I am trying to get MailMessage in .NET to return a string of the MIME message, but this is not provided in the delivered class. There's another excellent answer on how to create a C# extension method to monkey patch the class to provide the functionality. I am trying to port that to F# with a type extension, but I am getting hung up on how to provide the parameters (especially given that one of them is an F# keyword).
Would really appreciate an explanation of how this is done properly with the answer.
Here's what I have gotten so far (this will, of course, not currently compile):
open System.Net.Mail
module MailExtension =
type MailMessage with
member this.toEml mail =
let stream = new MemoryStream();
let mailWriterType = mail.GetType().Assembly.GetType("System.Net.Mail.MailWriter");
let mailWriter = Activator.CreateInstance(
type: mailWriterType,
bindingAttr: BindingFlags.Instance | BindingFlags.NonPublic,
binder: null,
args: new object[] { stream },
culture: null,
activationAttributes: null)
mail.GetType().InvokeMember(
name: "Send",
invokeAttr: BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.InvokeMethod,
binder: null,
target: mail,
args: new object[] { mailWriter, true, true });
Encoding.UTF8.GetString(stream.ToArray());
Upvotes: 1
Views: 131
Reputation: 13522
Here is a few hints on how to translate C# to F#:
Code that compiles:
open System
open System.IO
open System.Net.Mail
open System.Reflection
open System.Text
module MailExtension =
type MailMessage with
member this.toEml () =
use stream = new MemoryStream()
let mailWriterType = this.GetType().Assembly.GetType("System.Net.Mail.MailWriter")
let mailWriter = Activator.CreateInstance(
``type`` = mailWriterType,
bindingAttr = (BindingFlags.Instance ||| BindingFlags.NonPublic),
binder = null,
args = [| stream |],
culture = null,
activationAttributes = null)
this.GetType().InvokeMember(
name = "Send",
invokeAttr = (BindingFlags.Instance ||| BindingFlags.NonPublic ||| BindingFlags.InvokeMethod),
binder = null,
target = this,
args = [| mailWriter, true, true |])
Encoding.UTF8.GetString(stream.ToArray())
Then use:
open MailExtension
let m = new MailMessage()
m.toEml () |> ignore
Upvotes: 3