AutoMapper Alternative 2026 - Simple .NET Object Mapping (No Config!)

Greeting, developers! I made a simple AutoMapper .Net Library that serves a number of fybdamental needs, such as

  1. Object to Object Properties.
  2. Case-sensitive properties between objects (case insensitive mapping).
  3. Properties of objects with various datatypes (string to int convert c#).

Since AutoMappter Library has recently gone commercial, I made my own automapper hat eets my needs.

Asp.Net Core Mapping

This is the AutoMapper base code, which is used in libraries to change one object into another.


using System;
using System.Reflection;

namespace AutoMapper
{
    public class AutoMapper
    {
        public static TTarget Map(TSource source)
        where TTarget : new()
        {
            if (source == null) return default!;

            TTarget target = new TTarget();

            var sourceProps = typeof(TSource).GetProperties();
            var targetProps = typeof(TTarget).GetProperties();

            foreach (var tProp in targetProps)
            {
                if (!tProp.CanWrite) continue;

                // Case-insensitive match
                var sProp = sourceProps.FirstOrDefault(
                    sp => string.Equals(sp.Name, tProp.Name, StringComparison.OrdinalIgnoreCase)
                );

                if (sProp == null) continue;

                var sValue = sProp.GetValue(source);

                if (sValue == null)
                {
                    // If nullable → non-nullable, assign default value ("" for string)
                    if (!IsNullable(tProp.PropertyType))
                    {
                        tProp.SetValue(target, GetDefaultValue(tProp.PropertyType));
                    }
                    continue;
                }

                // Type matches → direct assign
                if (tProp.PropertyType == sProp.PropertyType)
                {
                    tProp.SetValue(target, sValue);
                    continue;
                }

                // Try convert types (string ↔ int, etc.)
                try
                {
                    var converted = Convert.ChangeType(sValue, tProp.PropertyType);
                    tProp.SetValue(target, converted);
                }
                catch
                {
                    // ignore conversion errors
                }
            }

            return target;
        }

        private static bool IsNullable(Type t)
        {
            return !t.IsValueType || Nullable.GetUnderlyingType(t) != null;
        }

        private static object GetDefaultValue(Type t)
        {
            if (t == typeof(string)) return string.Empty;
            return Activator.CreateInstance(t)!;
        }
    }
}


Main Entry : Execution Start


public static TTarget Map(TSource source) where TTarget : new()

The primary door is this one! Give the Source object, and receive the Target object. Target must have a parameterless constructor in order to use new().

Null Check


if (source == null) return default!;
TTarget target = new TTarget();

First check - source null? Return nothing. Else create new empty target object.

Get All Properties


var sourceProps = typeof(TSource).GetProperties();
var targetProps = typeof(TTarget).GetProperties();

Get ALL properties from both classes. Like collect all toys from two boxes!

Loop Through Target Properties


foreach (var tProp in targetProps)
{
    if (!tProp.CanWrite) continue;
    ---
    ---
}

Loop each target property. Skip if can't write (readonly).

Case-Insensitive Match


var sProp = sourceProps.FirstOrDefault(
    sp => string.Equals(sp.Name, tProp.Name, StringComparison.OrdinalIgnoreCase)
);


find matching property from source! firstname = FirstName? YES! Ignore small/big letters.

Get Source Value


if (sProp == null) continue;
var sValue = sProp.GetValue(source);

No match? Skip. Else get value from source property

Handle NULL Values


if (sValue == null)
{
    if (!IsNullable(tProp.PropertyType))
    {
        tProp.SetValue(target, GetDefaultValue(tProp.PropertyType));
    }
    continue;
}


Source value null? Check if target accepts null. No? Give smart default ("" for string, 0 for int)

SAME TYPE - Easy Copy


if (tProp.PropertyType == sProp.PropertyType)
{
    tProp.SetValue(target, sValue);
    continue;
}


Types same? Direct copy. Easy!

TYPE CONVERSION


try
{
    var converted = Convert.ChangeType(sValue, tProp.PropertyType);
    tProp.SetValue(target, converted);
}
catch { }


Different types? Try convert! "40" → 40 (int). Fail? Ignore silently

Helper Methods


private static bool IsNullable(Type t)  // Check null allowed?
private static object GetDefaultValue(Type t)  // Give smart defaults

Two helpers: Check nullable? Give default values?

Download Automapper Source from GitHub

Post a Comment

0 Comments