Take advantage of fluent interfaces and method chaining to make your code simple, readable, and understandable Credit: JJ Ying When working in applications you might often find that the source code has become so complex that it is difficult to understand and maintain. Fluent interfaces and method chaining are two concepts that attempt to make your code readable and simple. This article examines fluent interfaces and method chaining and how you can work with them in C#. To work with the code examples provided in this article, you should have Visual Studio 2019 installed in your system. If you don’t already have a copy, you can download Visual Studio 2019 here. Create a console application project in Visual Studio First off, let’s create a .NET Core console application project in Visual Studio. Assuming Visual Studio 2019 is installed in your system, follow the steps outlined below to create a new .NET Core console application project in Visual Studio. Launch the Visual Studio IDE. Click on “Create new project.” In the “Create new project” window, select “Console App (.NET Core)” from the list of templates displayed. Click Next. In the “Configure your new project” window, specify the name and location for the new project. Click Create. This will create a new .NET Core console application project in Visual Studio 2019. We’ll use this project in the subsequent sections of this article. Fluent interfaces and method chaining explained Method chaining is a technique in which methods are called on a sequence to form a chain and each of these methods return an instance of a class. These methods can then be chained together so that they form a single statement. A fluent interface is an object-oriented API that depends largely on method chaining. The goal of a fluent interface is to reduce code complexity, make the code readable, and create a domain specific language (DSL). It is a type of method chaining in which the context is maintained using a chain. You might already be using method chaining in your applications, knowingly or unknowingly. The following code snippet illustrates how methods are chained. var data = authorList.Where(a => a.Country == "USA") .OrderBy(a => a.AuthodId) .ToList(); In method chaining, when you call a method the context flows from the method called to another method, i.e., the next method in the chain. Hence the term “chaining” is used to describe this pattern. Method chaining example in C# The following code snippet provides a good example of method chaining. public class Program { public static void Main(string[] args) { var host = new WebHostBuilder() .UseKestrel() .UseContentRoot(Directory.GetCurrentDirectory()) .UseStartup<Startup>() .Build(); host.Run(); } } Fluent interfaces vs. method chaining While there are similarities between fluent interfaces and method chaining, there are also subtle differences between the two. Whereas fluid interfaces typically act on the same set of data, method chaining is used to change the aspects of a more complex object. In a fluent interface, the methods should return an instance of the same type. In method chaining, the methods may return instances of any class. It should also be noted that fluent interfaces are implemented using method chaining, but not all uses of method chaining are fluent interfaces. While method chaining usually works on a simple set of data, fluent interfaces are usually used to modify a complex object. Create an OrderBL class without method chaining in C# Select the console application project we created above in the Solution Explorer window and create a new class called OrderBL. Now, enter the following code in the new class. public class OrderBL { public Guid OrderId { get; set; } public int OrderType { get; set; } public DateTime OrderDate { get; set; } //Other properties relevant to the Order class goes here public OrderBL InitializeOrder(Guid OrderId) { if (OrderId == Guid.Empty) OrderId = Guid.NewGuid(); else this.OrderId = OrderId; OrderType = 2; OrderDate = DateTime.Now; return this; } public void ValidateOrder(Guid OrderId) { //Write your code to validate the order here } public void SearchOrder(Guid OrderId) { //Write your code here to search an order in the database. } public void ProcessOrder() { //Write your code here to process an order. } public void CancelOrder(Guid OrderId) { //Write your code here to cancel an order. } public void SaveOrder() { //Write your code here to save order information in the db. } } You can now invoke the methods of the OrderBL class in a sequence in the Main method of the Program class as shown in the code snippet given below. static void Main(string[] args) { Guid OrderId = Guid.Parse("9043f30c-446f-421f-af70-234fe8f57c0d"); OrderBL orderBL = new OrderBL(); orderBL.InitializeOrder(OrderId); orderBL.ValidateOrder(OrderId); orderBL.ProcessOrder(); orderBL.SaveOrder(); Console.ReadKey(); } Create an OrderBL class with method chaining in C# To implement method chaining, you should return an instance from the methods you want to be in the chain. In the OrderBL example above, the methods have been called in a sequence but you’ve had to write multiple lines of code — one for each method call. So, to take advantage of method chaining here, you should change the return type of the methods to a class name such as OrderBL. You should also return an instance of a class (not necessarily OrderBL) from the methods you want to participate in the chain. For the sake of simplicity let’s assume that the return type of the participating methods is OrderBL. You should now specify return this; from these participating methods. The updated version of the OrderBL class is given below. public class OrderBL { Guid OrderId { get; set; } int OrderType { get; set; } DateTime OrderDate { get; set; } //Other properties relevant to the Order class goes here public OrderBL InitializeOrder(Guid OrderId) { if (OrderId == Guid.Empty) OrderId = Guid.NewGuid(); else this.OrderId = OrderId; OrderType = 2; OrderDate = DateTime.Now; return this; } public OrderBL ValidateOrder(Guid OrderId) { return this; //Write your code to validate the order here } public OrderBL SearchOrder(Guid OrderId) { return this; //Write your code here to search an order in the database. } public OrderBL ProcessOrder() { return this; //Write your code here to process an order. } public void CancelOrder(Guid OrderId) { //Write your code here to cancel an order. } public void SaveOrder() { //Write your code here to save order information in the db. } } You can now call the methods in a chain as illustrated in the code snippet given below. static void Main(string[] args) { Guid OrderId = Guid.Parse("9043f30c-446f-421f-af70-234fe8f57c0d"); OrderBL orderBL = new OrderBL(); orderBL.InitializeOrder(OrderId).ValidateOrder(OrderId). ProcessOrder().SaveOrder(); Console.ReadKey(); } Note that because the return type of Save is void, the method chain shown in the preceding code snippet ends there. You might want to use fluent interfaces and method chaining when you want your code to be simple and readable by non-developers. The goal of fluent interfaces is to make the code simple, readable, and maintainable. You can implement fluent interfaces in C# using method chaining, factory classes, and named parameters. I’ll have more to say about fluent interfaces and method chaining in a future post here. How to do more in C#: How to unit test static methods in C# How to refactor God objects in C# How to use ValueTask in C# How to use immutability in C How to use const, readonly, and static in C# How to use data annotations in C# How to work with GUIDs in C# 8 When to use an abstract class vs. interface in C# How to work with AutoMapper in C# How to use lambda expressions in C# How to work with Action, Func, and Predicate delegates in C# How to work with delegates in C# How to implement a simple logger in C# How to work with attributes in C# How to work with log4net in C# How to implement the repository design pattern in C# How to work with reflection in C# How to work with filesystemwatcher in C# How to perform lazy initialization in C# How to work with MSMQ in C# How to work with extension methods in C# How to us lambda expressions in C# When to use the volatile keyword in C# How to use the yield keyword in C# How to implement polymorphism in C# How to build your own task scheduler in C# How to work with RabbitMQ in C# How to work with a tuple in C# Exploring virtual and abstract methods in C# How to use the Dapper ORM in C# How to use the flyweight design pattern in C# Related content feature 14 great preprocessors for developers who love to code Sometimes it seems like the rules of programming are designed to make coding a chore. Here are 14 ways preprocessors can help make software development fun again. By Peter Wayner Nov 18, 2024 10 mins Development Tools Software Development feature Designing the APIs that accidentally power businesses Well-designed APIs, even those often-neglected internal APIs, make developers more productive and businesses more agile. By Jean Yang Nov 18, 2024 6 mins APIs Software Development news Spin 3.0 supports polyglot development using Wasm components Fermyon’s open source framework for building server-side WebAssembly apps allows developers to compose apps from components created with different languages. By Paul Krill Nov 18, 2024 2 mins Microservices Serverless Computing Development Libraries and Frameworks news Go language evolving for future hardware, AI workloads The Go team is working to adapt Go to large multicore systems, the latest hardware instructions, and the needs of developers of large-scale AI systems. By Paul Krill Nov 15, 2024 3 mins Google Go Generative AI Programming Languages Resources Videos