Skip to content
/ Remute Public

C# library to create new immutable object applying lambda expressions to the existing immutable object

License

Notifications You must be signed in to change notification settings

ababik/Remute

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

69 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Remute

Remute C# library to create new immutable object applying lambda expressions to the existing immutable object.

Examples (flat and nested object structures)

For example define immutable class:

public class Employee
{
    public string FirstName { get; }

    public string LastName { get; }

    public Employee(string firstName, string lastName)
    {
        FirstName = firstName;
        LastName = lastName;
    }
}

Apply modification:

var remute = new Remute();
var expected = new Employee("John", "Doe");
var actual = remute.With(expected, x => x.FirstName, "Foo");

Generic method With returns new object where first name is updated:

Assert.AreNotSame(expected.FirstName, actual.FirstName);
Assert.AreSame(expected.LastName, actual.LastName);

Remute works with immutable nested object structures (including C# 9 records).

Define few more immutable classes:

public class Department
{
    public string Title { get; }

    public Employee Manager { get; }

    public Department(string title, Employee manager)
    {
        Title = title;
        Manager = manager;
    }
}

public class Organization
{
    public string Name { get; }

    public Department DevelopmentDepartment { get; }

    public Organization(string name, Department developmentDepartment)
    {
        Name = name;
        DevelopmentDepartment = developmentDepartment;
    }
}

Remute first name of the manager of the development department:

var expected = 
    new Organization("Organization", 
        new Department("Development Department", 
            new Employee("John", "Doe")));
            
var actual = remute.With(expected, x => x.DevelopmentDepartment.Manager.FirstName, "Foo");

Actual object has updated references for DevelopmentDepartment, Manager and FirstName. All other object references (like Organization.Name, Department.Title and Employee.LastName) remain the same.

Assert.AreNotSame(expected, actual);
Assert.AreNotSame(expected.DevelopmentDepartment, actual.DevelopmentDepartment);
Assert.AreNotSame(expected.DevelopmentDepartment.Manager, actual.DevelopmentDepartment.Manager);
Assert.AreSame(expected.Name, actual.Name);
Assert.AreSame(expected.DevelopmentDepartment.Title, expected.DevelopmentDepartment.Title);

Multiple constuctors and parameter names matching

By default Remute expects immutable type to have single constructor with parameters matching property names (case-insensetive). Use ActivationConfiguration to change this default behaviour. Check issue for more details.

var config = new ActivationConfiguration()
    .Configure<User>(x => new User(x.FirstName, x.LastName));

var remute = new Remute(config);

Syntax sugar

There is an extension method enabling chained modifications on any object.

using Remutable.Extensions;
...
var employee = new Employee(Guid.NewGuid(), "Joe", "Doe");

var actual = employee
    .Remute(x => x.FirstName, "Foo")
    .Remute(x => x.LastName, "Bar");

Assert.AreEqual("Foo", actual.FirstName);
Assert.AreEqual("Bar", actual.LastName);

Performance notes

Remute does not use reflection / Activator.CreateInstance for object creation. Instead cached lambda expressions are used that demonstrates great performance.

Get it

Remute is available as .Net Standard assembly via Nuget

dotnet add package Remute or Install-Package Remute

About

C# library to create new immutable object applying lambda expressions to the existing immutable object

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages