The content you're reading is getting on in years
This post is on the older side and its content may be out of date.
Be sure to visit our blogs homepage for our latest news, updates and information.
Using Sitefinity’s Fluent API is a great way to write readable code while extending the capabilities of a project, and developers can extend the Fluent API as well.
Sitefinity includes several APIs. Along with the Fluent API, it includes an imperative API and a REST API. Each is useful for particular tasks, but I really enjoy working with fluent APIs. Its declarative style makes code more readable, going from left-to-write in the style of many natural languages.
Many .NET developers are familiar with the fluent interface provided by LINQ to Objects, but all .NET developers should be familiar with a fluent interface contained within the .NET Framework before Eric Evans coined the term in 2005.
In Figure 1, the Standardize method transforms a string. If one were to pass in the value Ada Lovelace, the return value would be ada-lovelace. The body of the method calls a series of methods beginning with Trim on the path variable, each returning a new string. This is a clear representation of a fluent interface: it utilizes method chaining and the context remains the same in each call.
Sitefinity’s Fluent API is more complex than the fluent interface of the System.String class. Instead of immutable data transformations, it produces side effects (changes in state), and its context is more extensive than can be represented with one class. It uses a progressive interface. Each step guides you to the next.
Figure 2 demonstrates a very clear path in creating a new, empty blog post then saving the changes. The documentation goes into more detail, but Visual Studio’s IntelliSense will guide you as well. At each step in the chain, Visual Studio shows the next, valid options.
C# developers can use extension methods to extend any fluent interface. To illustrate this, consider the method operating on string in Figure 1. If I make this an extension method, I have in effect substituted a word for a lengthy phrase in the domain specific language (in this case, the string transformation DSL).
This technique is useful for removing duplicate method chains found throughout a project. If appropriate names are used, the code becomes more readable. Additionally, the code is easier to test since you can ensure that particular chain is correct.
You may wish to do more than simply create definitions. Andy Jeffery asked the following question in the Sitefinity Devs community on Google+.
With the fluent API I can use the following to get all "live" images into a list..
App.WorkWith().Images().Where(b => b.Status == ContentLifecycleStatus.Live).Get().ToList();
Now, if I have a Dynamic Content Item (called Contact), how would I use the fluent API to do similar?
The Fluent API does not include this functionality, but a commenter suggested a solution from the imperative API.
DynamicModuleManager.GetManager().GetDataItems(TypeResolutionService.ResolveType("Telerik.Sitefinity.DynamicTypes.Model.your_contact_type..")).Where(c => c.Status == ContentLifecycleStatus.Live)
To create a fluent solution with minimal hassle, I’m going to use the provided imperative code and the base classes used by the Fluent API. I begin with the BasePluralFacade<TCurrentFacade, TSingularFacade, TParentFacade, TDataItem> class. It only requires a BaseFacade for the TSingularFacade generic parameter. However, using the BaseSingularFacade<TCurrentFacade, TParentFacade, TDataItem> class is straightforward, and I won’t need to provide extra functionality for single items.
Plugging these facades into the Fluent API requires a simple extension method for the FluentSitefinity class. I chose not to extend FluentDynamicData since it hides AppSettings.
That’s it. Since I’m using the base façade classes, everything else falls into place. Andy can now use the Fluent API to access dynamic content.
The solution to extending any fluent API in C# is extension methods. Extensive fluent APIs, such as the one found in Sitefinity, may require some research in its interfaces and classes to achieve an optimal result. It isn’t necessary to follow the original API exactly, but consistency is important. You’re adding onto a language, and the accent isn’t as important as being understood.
Update: I created the project using a type I created through code rather than the module builder. I updated the code to support passing in the fully qualified string name and posted it to a new GitHub project, Sitefinity and Beyond.View all posts from Chris Eargle on the Progress blog. Connect with us about all things application development and deployment, data integration and digital business.
Let our experts teach you how to use Sitefinity's best-in-class features to deliver compelling digital experiences.
Learn MoreSubscribe to get all the news, info and tutorials you need to build better business apps and sites
Progress collects the Personal Information set out in our Privacy Policy and the Supplemental Privacy notice for residents of California and other US States and uses it for the purposes stated in that policy.
You can also ask us not to share your Personal Information to third parties here: Do Not Sell or Share My Info
We see that you have already chosen to receive marketing materials from us. If you wish to change this at any time you may do so by clicking here.
Thank you for your continued interest in Progress. Based on either your previous activity on our websites or our ongoing relationship, we will keep you updated on our products, solutions, services, company news and events. If you decide that you want to be removed from our mailing lists at any time, you can change your contact preferences by clicking here.