How to use fluent interfaces and method chaining in C#
By FoxLearn 1/6/2025 4:04:56 AM 65
Fluent interfaces allow for a more natural, readable flow of code by enabling methods to be called in a sequence, while method chaining allows multiple methods to be invoked on the same object in a single line.
Understanding Fluent Interfaces and Method Chaining
- Method chaining is a technique where methods are called in sequence, each returning an instance of a class, allowing them to be chained into a single statement.
- A fluent interface is an object-oriented API that relies on method chaining to reduce code complexity, improve readability, and create a domain-specific language (DSL).
Here's an example of how methods can be chained together:
var results = products.Where(p => p.Price > 100) .OrderBy(p => p.Name) .Select(p => p.Name) .ToList();
In method chaining, each method call passes its result to the next method in the sequence, allowing them to be linked together. This flow of context between methods is why it's called "chaining."
Example of Method Chaining in C#
Here's an example of method chaining in action:
public class Program { public static void Main(string[] args) { var logger = new LoggerConfiguration() .WriteTo.Console() .WriteTo.File("logs.txt") .CreateLogger(); logger.Information("Logging started."); } }
In this example, methods are chained together to configure the logger, allowing for a clear and concise setup in a single statement.
Fluent interfaces vs method chaining
Fluent interfaces and method chaining share similarities but also have key differences.
- Fluent interfaces typically operate on the same set of data and return an instance of the same type, while method chaining is used to modify aspects of a more complex object and may return instances of different classes.
- Fluent interfaces are built using method chaining, but not all method chaining implementations qualify as fluent interfaces.
- Fluent interfaces are often used to work with complex objects, while method chaining generally handles simpler data.
Create a ProductBL Class without Method Chaining in C#
Let's start by defining a ProductBL
class with standard methods. These methods will be invoked in sequence in the Main
method:
public class ProductBL { public Guid ProductId { get; set; } public string ProductName { get; set; } public decimal Price { get; set; } // Other relevant properties for the Product class public ProductBL InitializeProduct(Guid ProductId, string ProductName) { this.ProductId = ProductId == Guid.Empty ? Guid.NewGuid() : ProductId; this.ProductName = ProductName; this.Price = 100; // Default price return this; } public void ValidateProduct() { // Validation logic for the product } public void UpdatePrice(decimal newPrice) { // Logic to update the price of the product this.Price = newPrice; } public void SaveProduct() { // Logic to save the product in the database } }
In the Main
method, you would call each method individually.
static void Main(string[] args) { Guid ProductId = Guid.NewGuid(); string ProductName = "Laptop"; ProductBL productBL = new ProductBL(); productBL.InitializeProduct(ProductId, ProductName); productBL.ValidateProduct(); productBL.UpdatePrice(120); productBL.SaveProduct(); Console.ReadKey(); }
Create a ProductBL Class with Method Chaining in C#
Now, let's modify the ProductBL
class to support method chaining by returning the ProductBL
instance from each method:
public class ProductBL { public Guid ProductId { get; set; } public string ProductName { get; set; } public decimal Price { get; set; } // Other properties for the Product class public ProductBL InitializeProduct(Guid ProductId, string ProductName) { this.ProductId = ProductId == Guid.Empty ? Guid.NewGuid() : ProductId; this.ProductName = ProductName; this.Price = 100; // Default price return this; } public ProductBL ValidateProduct() { // Validation logic return this; } public ProductBL UpdatePrice(decimal newPrice) { this.Price = newPrice; return this; } public void SaveProduct() { // Logic to save the product in the database } }
With method chaining in place, the Main
method now becomes more concise:
static void Main(string[] args) { Guid ProductId = Guid.NewGuid(); string ProductName = "Laptop"; ProductBL productBL = new ProductBL(); productBL.InitializeProduct(ProductId, ProductName) .ValidateProduct() .UpdatePrice(120) .SaveProduct(); Console.ReadKey(); }
Note that, as before, the method SaveProduct()
does not return a ProductBL
instance, so the chain ends there.
Advantages of Method Chaining and Fluent Interfaces
Method chaining and fluent interfaces allow for a more readable, expressive, and compact way of writing code. By chaining methods, you can reduce the need for repetitive code and make the flow of operations easier to follow. This can be particularly useful for configurations or operations on complex objects, and it helps improve code maintainability and simplicity.
- How to fix 'Failure sending mail' in C#
- How to Parse a Comma-Separated String from App.config in C#
- How to convert a dictionary to a list in C#
- How to retrieve the Executable Path in C#
- How to validate an IP address in C#
- How to retrieve the Downloads Directory Path in C#
- C# Tutorial
- Dictionary with multiple values per key in C#