简单的模板问题。有人可以看看这个小提琴吗?我有一个
ClaimMessageController : MessageController
、ClaimMessage : Message
和 MessageController.Send(TMessage)
,我希望能够将 ClaimMessage
传递给 ClaimMessageController
以获取用于 URL 替换的 ClaimId。
https://dotnetfiddle.net/FBh7yS
using System;
using System.Threading.Tasks;
using System.Reflection;
using System.IO;
using System.Linq;
public class MailWrapper {
public async Task Send(string recipientEmailAddress, string recipientDisplayName, string subject, string htmlBody) {}
}
public class Message
{
public string To { get; set; }
public string ToName { get; set; }
}
public abstract class MessageController<TMessage> where TMessage : Message
{
private readonly MailWrapper _mailWrapper;
protected abstract string TemplatePath { get; }
protected abstract string Subject { get; }
protected MessageController(MailWrapper mailWrapper)
{
_mailWrapper = mailWrapper;
}
public async Task Send(TMessage message) =>
await _mailWrapper.Send(message.To, message.ToName, RenderSubject(message), await RenderEmail(message));
private string RenderSubject(Message message) =>
message.GetType().GetProperties().Aggregate(Subject, (current, property) =>
current.Replace("{{" + property.Name + "}}", property.GetValue(message)?.ToString(),
StringComparison.InvariantCultureIgnoreCase));
public virtual async Task<string> RenderEmail(Message message) =>
message.GetType().GetProperties().Aggregate(
await new StreamReader(Assembly.GetExecutingAssembly().GetManifestResourceStream(TemplatePath)!)
.ReadToEndAsync(),
(current, property) =>
current.Replace("{{" + property.Name + "}}", property.GetValue(message)?.ToString(),
StringComparison.InvariantCultureIgnoreCase));
}
public class ClaimMessage : Message
{
public int ClaimId { get; set; }
}
public abstract class ClaimMessageController<TMessage> : MessageController<ClaimMessage>
{
private readonly MailWrapper _mailWrapper;
protected ClaimMessageController(MailWrapper mailWrapper) : base(mailWrapper)
{
_mailWrapper = mailWrapper;
}
public override Task<string> RenderEmail(TMessage message)
{
return base.RenderEmail(message);
}
public override async Task<string> RenderEmail(TMessage message) => (await base.RenderEmail((ClaimMessage)message)).Replace(
"{{ClaimUrl}}", $"https://foo/claim/{message.ClaimId}",
StringComparison.InvariantCultureIgnoreCase);
}
public abstract class ClaimMessageController<TMessage>
: MessageController<ClaimMessage>
应该是
public abstract class ClaimMessageController<TMessage>
: MessageController<TMessage>
where TMessage : Message
您还存在相互冲突的
RenderEmail
覆盖。我认为摆脱第一个。
然后它还有一个不必要/不正确的转换为
ClaimMessage
。 RenderEmail
覆盖应如下所示:
public override async Task<string> RenderEmail(
TMessage message
) =>
(await base.RenderEmail(message))
.Replace(
"{{ClaimUrl}}",
$"https://foo/claim/{((ClaimMessage)message).ClaimId}",
StringComparison.InvariantCultureIgnoreCase
);