如今,“Fluent接口(interface)”是一个相当热门的话题。 C#3.0具有一些不错的功能(尤其是扩展方法),可以帮助您实现它们。

仅供引用,流畅的API意味着每个方法调用都返回有用的东西,通常是您调用该方法的对象,因此您可以保持链接。 Martin Fowler用Java示例here讨论了它。这个概念有点像这样:

var myListOfPeople = new List<Person>();

var person = new Person();
person.SetFirstName("Douglas").SetLastName("Adams").SetAge(42).AddToList(myListOfPeople);

我已经在C#中看到了一些非常有用的流畅接口(interface)(一个示例是用于验证在an earlier StackOverflow question I had asked中找到的参数的流畅方法。这让我震惊了。它能够提供高度可读的语法来表示参数验证规则,如果没有,异常(exception)情况下,它能够避免实例化任何对象!因此,对于“正常情况”而言,开销很小。这个花絮在短时间内教会了我巨大的数量。我想找到更多类似的东西)。

因此,我想通过观察和讨论一些出色的例子来学习更多。那么,是您在C#中制作或看到的一些优秀的流畅接口(interface),又是什么使它们如此有值(value)?

谢谢。

最佳答案

方法参数验证的荣誉,您为我们的流畅API提供了新的思路。无论如何我都讨厌我们的前提条件检查...

我为开发中的新产品构建了可扩展性系统,您可以在其中流畅地描述可用的命令,用户界面元素等。它在StructureMap和FluentNHibernate之上运行,它们也是不错的API。

MenuBarController mb;
// ...
mb.Add(Resources.FileMenu, x =>
{
  x.Executes(CommandNames.File);
  x.Menu
    .AddButton(Resources.FileNewCommandImage, Resources.FileNew, Resources.FileNewTip, y => y.Executes(CommandNames.FileNew))
    .AddButton(null, Resources.FileOpen, Resources.FileOpenTip, y =>
    {
      y.Executes(CommandNames.FileOpen);
      y.Menu
        .AddButton(Resources.FileOpenFileCommandImage, Resources.OpenFromFile, Resources.OpenFromFileTop, z => z.Executes(CommandNames.FileOpenFile))
        .AddButton(Resources.FileOpenRecordCommandImage, Resources.OpenRecord, Resources.OpenRecordTip, z => z.Executes(CommandNames.FileOpenRecord));
     })
     .AddSeperator()
     .AddButton(null, Resources.FileClose, Resources.FileCloseTip, y => y.Executes(CommandNames.FileClose))
     .AddSeperator();
     // ...
});

您可以配置所有可用的命令,如下所示:
Command(CommandNames.File)
  .Is<DummyCommand>()
  .AlwaysEnabled();

Command(CommandNames.FileNew)
  .Bind(Shortcut.CtrlN)
  .Is<FileNewCommand>()
  .Enable(WorkspaceStatusProviderNames.DocumentFactoryRegistered);

Command(CommandNames.FileSave)
  .Bind(Shortcut.CtrlS)
  .Enable(WorkspaceStatusProviderNames.DocumentOpen)
  .Is<FileSaveCommand>();

Command(CommandNames.FileSaveAs)
  .Bind(Shortcut.CtrlShiftS)
  .Enable(WorkspaceStatusProviderNames.DocumentOpen)
  .Is<FileSaveAsCommand>();

Command(CommandNames.FileOpen)
  .Is<FileOpenCommand>()
  .Enable(WorkspaceStatusProviderNames.DocumentFactoryRegistered);

Command(CommandNames.FileOpenFile)
  .Bind(Shortcut.CtrlO)
  .Is<FileOpenFileCommand>()
  .Enable(WorkspaceStatusProviderNames.DocumentFactoryRegistered);

Command(CommandNames.FileOpenRecord)
  .Bind(Shortcut.CtrlShiftO)
  .Is<FileOpenRecordCommand>()
  .Enable(WorkspaceStatusProviderNames.DocumentFactoryRegistered);

我们的 View 使用工作区提供给他们的服务,为标准编辑菜单命令配置其控件,他们只是告诉它观察它们:
Workspace
  .Observe(control1)
  .Observe(control2)

如果用户使用Tab键选择了控件,则工作区将自动获取该控件的适当适配器,并提供撤消/重做和剪贴板操作。

它帮助我们大大减少了设置代码,并使其更具可读性。

我忘了讲讲我们在WinForms MVP模型演示者中使用的库来验证 View :FluentValidation。真的很容易,可以测试,很好!

09-19 20:37