如今,“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。真的很容易,可以测试,很好!