MapSharp 1.0.0

There is a newer version of this package available.
See the version list below for details.
dotnet add package MapSharp --version 1.0.0                
NuGet\Install-Package MapSharp -Version 1.0.0                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="MapSharp" Version="1.0.0" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add MapSharp --version 1.0.0                
#r "nuget: MapSharp, 1.0.0"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install MapSharp as a Cake Addin
#addin nuget:?package=MapSharp&version=1.0.0

// Install MapSharp as a Cake Tool
#tool nuget:?package=MapSharp&version=1.0.0                

MapSharp

MapSharp is a powerful C# source generator library designed to automate the creation of type-safe mapping extension methods between your classes. Leveraging compile-time code generation, MapSharp eliminates the need for manual mapping configurations, enhancing both developer productivity and application performance.

Table of Contents

Features

  • Automatic Extension Method Generation: Seamlessly generate extension methods for mapping between source and destination types without writing boilerplate code.

  • Support for Nested Objects: Handle complex object hierarchies with ease, ensuring that nested properties are accurately mapped.

  • Comprehensive Collection Handling:

    • Arrays: Automatically map array properties using .ToArray().
    • Lists and Collections: Support IList<T>, List<T>, ICollection<T>, and other collection types with appropriate conversions using .ToList().
    • Enumerables: Efficiently handle IEnumerable<T> without unnecessary type conversions.
  • Asynchronous Property Mappings: Generate asynchronous mapping methods that can handle async operations within property mappings, ensuring non-blocking transformations.

  • Direct Method Invocation Handling: Accurately detect and transform direct method calls within mapping expressions, ensuring that methods are correctly prefixed and invoked.

  • Reverse Mapping Support: Easily generate reverse mappings with support for ReverseMap(), allowing bi-directional transformations between types.

  • Customizable Mappings: Define custom mapping logic for specific properties using fluent API configurations like .ForMember().

  • Diagnostic Reporting: Integrated diagnostics to help identify and resolve mapping issues during compile time, enhancing reliability.

Installation

Install the MapSharp package via NuGet:

dotnet add package MapSharp

Or using the Package Manager Console:

Install-Package MapSharp

Usage

MapSharp operates by defining mappings between your source and destination types. These mappings are then used to generate extension methods that perform the actual object-to-object transformations. Here's how to set it up and use it in your project.

Defining Mappings

Typically, you'll configure your mappings in a central location, such as during application startup or in a dedicated mapping configuration class. For example:

using MapSharp;

public class MappingConfiguration : IProfile
{
    public Configure(Profile profile)
    {
        profile.CreateMap<User, UserModel>()
            .ForMember(dest => dest.Name, async src => await UpdateDataAsync(src.Name))
            .ForMember(dest => dest.Friends, src => src.Friends)
            .ForMember(dest => dest.Hobbies, src => src.Hobbies)
            .ReverseMap();

        profile.CreateMap<Hobby, HobbyModel>()
            .ReverseMap();
    }

    private async Task<string> UpdateDataAsync(string name)
    {
        // Implementation for updating data asynchronously
        await Task.Delay(100); // Simulate async work
        return $"Updated {name}";
    }
}

Generated Extension Methods

After defining your mappings, MapSharp will automatically generate the necessary extension methods during compilation. These methods facilitate seamless and efficient object-to-object mappings.

using System;
using System.Threading.Tasks;
using System.Linq;

namespace YourNamespace
{
    public static class UserMappingExtensions
    {
        public static async Task<UserModel> ToUserModelAsync(this User source)
        {
            if (source == null) throw new ArgumentNullException(nameof(source));

            var destination = new UserModel
            {
                Name = await source.UpdateDataAsync(source.Name),
                Friends = source.Friends?.Select(item => item.ToUserModel()).ToList(),
                Hobbies = source.Hobbies?.Select(item => item.ToHobbyModel()),
            };

            return destination;
        }
    }
}

Examples

Basic Mapping

Consider the following classes for a simple mapping example:

public class User
{
    public string Name { get; set; }
    public int Age { get; set; }
    public IList<User> Friends { get; set; }
    public IEnumerable<Hobby> Hobbies { get; set; }
}

public class UserModel
{
    public string Name { get; set; }
    public int Age { get; set; }
    public IList<UserModel> Friends { get; set; }
    public IEnumerable<HobbyModel> Hobbies { get; set; }
}

public class Hobby
{
    public string Description { get; set; }
}

public class HobbyModel
{
public string Description { get; set; }
}

public class HobbyModel
{
    public string Description { get; set; }
}

Define the mappings:

profile.CreateMap<User, UserModel>()
    .ForMember(dest => dest.Name, async src => await UpdateDataAsync(src.Name))
    .ReverseMap();

profile.CreateMap<Hobby, HobbyModel>()
    .ReverseMap();

Generated Extension Method:

public static async Task<UserModel> ToUserModelAsync(this User source)
{
    if (source == null) throw new ArgumentNullException(nameof(source));

    var destination = new UserModel
    {
        Name = await source.UpdateDataAsync(source.Name),
        Age = source.Age,
        Friends = source.Friends?.Select(item => item.ToUserModel()).ToList(),
        Hobbies = source.Hobbies?.Select(item => item.ToHobbyModel()),
    };

    return destination;
}

Handling Collections and Arrays

For cases where your model contains collections or arrays, the mapping configuration can handle these scenarios as well.

public class Group
{
    public string GroupName { get; set; }
    public User[] Members { get; set; }
}

public class GroupModel
{
    public string GroupName { get; set; }
    public UserModel[] Members { get; set; }
}

Define the mapping:

profile.CreateMap<Group, GroupModel>()
    .ReverseMap();

Generated Extension Method:

public static GroupModel ToGroupModel(this Group source)
{
    if (source == null) throw new ArgumentNullException(nameof(source));

    return new GroupModel
    {
        GroupName = source.GroupName,
        Members = source.Members?.Select(item => item.ToUserModel()).ToArray(),
    };
}

Asynchronous Property Mappings

When working with asynchronous methods in your mappings, you can define them just like synchronous methods.

public class Order
{
    public string OrderId { get; set; }
    public decimal Amount { get; set; }
    public string CustomerName { get; set; }
}

public class OrderModel
{
    public string OrderId { get; set; }
    public decimal Amount { get; set; }
    public string CustomerName { get; set; }
}

profile.CreateMap<Order, OrderModel>()
    .ForMember(dest => dest.CustomerName, async src => await FetchCustomerNameAsync(src.CustomerName))
    .ReverseMap();

Generated Extension Method:

public static async Task<OrderModel> ToOrderModelAsync(this Order source)
{
    if (source == null) throw new ArgumentNullException(nameof(source));

    var destination = new OrderModel
    {
        OrderId = source.OrderId,
        Amount = source.Amount,
        CustomerName = await source.FetchCustomerNameAsync(source.CustomerName),
    };

    return destination;
}

License

Distributed under the MIT License. See LICENSE for more information.

This README was generated with ❤️ by MapSharp.

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
1.0.1 76 9/20/2024
1.0.0 75 9/20/2024