如何将流利风格的语法糖与 c# 属性声明一起使用



我以前从未使用过流畅的代码风格。因此,这是我第一次尝试使用 C# 属性声明以流畅的风格开发一些东西,但我收到一个错误。谁能帮我?

public class MailTemplate
{
    string _MailBody = "";
    public MailTemplate MailBody
    {
        get { return _MailBody; }
        set { _MailBody = value ; }
    }
    string _Subject = "";
    public MailTemplate Subject
    {
        get { return _Subject; }
        set { _Subject = value; }
    }
    string _MailFrom = "";
    public MailTemplate MailFrom
    {
        get { return _MailFrom; }
        set { _MailFrom = value; }
    }
}

请帮助我如何分配或初始化邮件正文,以后也可以使用相同的属性名称进行读取。我认为在流畅风格开发的情况下不能使用属性。这里需要一些光线。

MailTemplate类的流畅构建器界面如下所示:

public class MailTemplateBuilder
{
    string _body;
    string _subject;
    string _sender;
    public MailTemplateBuilder WithBody(string body)
    {
        _body = body;
        return this;
    }
    public MailTemplateBuilder WithSubject(string subject)
    {
        _subject = subject;
        return this;
    }
    public MailTemplateBuilder WithSender(string sender)
    {
        _sender = sender;
        return this;
    }
    public MailTemplate Build()
    {
        return new MailTemplate(_sender, _subject, _body);
    }
}

用法如下所示:

var template = _builder.WithBody("body")
                       .WithSubject("subject")
                       .WithSender("sender")
                       .Build();
<小时 />

另一种方法是使用扩展方法:

public static class MailTemplateBuilder
{
    public static MailTemplate WithBody(this MailTemplate item, string body)
    {
        item.MailBody = body;
        return item;
    }
    public static MailTemplate WithSubject(this MailTemplate item, string subject)
    {
        item.MailSubject = subject;
        return item;
    }
    public static MailTemplate WithSender(this MailTemplate item, string sender)
    {
        item.MailFrom = sender;
        return item;
    }
}

用法现在如下所示:

var template = new MailTemplate().WithBody("body")
                                 .WithSubject("subject")
                                 .WithSender("sender");

请注意:
在这两种情况下,MailTemplate类都不会被此流畅接口的代码污染。这将是一个简单的类:

public class MailTemplate
{
    public string MailBody { get; set; } = "";
    public string Subject { get; set; } = "";
    public string MailFrom { get; set; } = "";
}

因此,在使用提供的任何一个 fluent 接口创建该实例后,只需通过访问属性来读取值:

var body = template.MailBody;

一些框架,例如 FluentNHibernate,只是将自己作为 lambda 传递:

MailTemplate
    .ConfigureWith(mt => mt.MailBody = "hello world")
    .ConfigureWith(mt => mt.MailFrom = "rdingwall@gmail.com")
    .DoSomeOtherStuff()
    .Build();

实现方式为:

public class MailTemplate
{
    // regular auto properties
    public string MailFrom { get; set; }
    public string MailBody { get; set; }
    public MailTemplate ConfigureWith(Action<MailTemplate> func)
    {
        func(this);
        return this;
    }
    ...
}

您不能使用这样的属性来编写流畅的接口 - 字段的类型为 string,但您的属性都尝试返回 MailTemplate

不要使用属性,而是将它们转换为可以链接在一起的方法

public class MailTemplate
{
    string _MailBody = "";
    public MailTemplate Body(string mailBody)
    {
        _MailBody = mailBody;
        return this;
    }
    ...

正如@Richard所说,FluentNHibernate只是将自己作为lambda传递。 您也可以使用 C# 执行相同的操作。

public class MailTemplate
{
   
    public string To { get; set; }
    public string From { get; set; }
    public string Subject { get; set; }
    public string Body { get; set; }
    public string Attachement { get; set; }
    public static MailTemplate Configure { get => new MailTemplate(); }

    public MailTemplate With(Action<MailTemplate> func)
    {
        func(this);
        return this;
    }
    internal void Build()
    {
        Console.WriteLine("Sending the mail....");
    }
}

这是调用此方法的方法

MailTemplate
            .Configure
                .With(mt => mt.To = "michaelameyaw7@gmail.com")
                .With(mt => mt.From = "persol.system@gmail.com")
                .With(mt => mt.Subject = "Fluent Try Test")
                .With(mt => mt.Body = "Hello, this is mail body")
                .With(mt => mt.Attachement = "file.pdf")
           .Build();

最新更新