Skip to content

Commit

Permalink
WORKSHOP
Browse files Browse the repository at this point in the history
  • Loading branch information
SonicTheCat committed Mar 20, 2019
1 parent 8fcd219 commit 6385fee
Show file tree
Hide file tree
Showing 9 changed files with 285 additions and 0 deletions.
25 changes: 25 additions & 0 deletions 08.Workshop - CustomAutoMapper/CustomAutoMapper.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.28307.489
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CustomAutoMapper", "CustomAutoMapper\CustomAutoMapper.csproj", "{A06363BE-D5AD-4292-83A7-2E1DF865F631}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{A06363BE-D5AD-4292-83A7-2E1DF865F631}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A06363BE-D5AD-4292-83A7-2E1DF865F631}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A06363BE-D5AD-4292-83A7-2E1DF865F631}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A06363BE-D5AD-4292-83A7-2E1DF865F631}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {3DD7ECA6-1CD4-4D40-9002-618AB84965EF}
EndGlobalSection
EndGlobal
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.2</TargetFramework>
</PropertyGroup>

</Project>
11 changes: 11 additions & 0 deletions 08.Workshop - CustomAutoMapper/CustomAutoMapper/ExceptionUtils.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
namespace CustomAutoMapper
{
public static class ExceptionUtils
{
public const string NullableSourceValueGetMethod = "The get method of the source value provided is null";

public const string NullSourceValueOrReturnType = "The source or the return type is null";

public const string NullSource = "The source provided is null";
}
}
102 changes: 102 additions & 0 deletions 08.Workshop - CustomAutoMapper/CustomAutoMapper/Mapper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
using System;
using System.Collections;
using System.Linq;
using System.Reflection;

namespace CustomAutoMapper
{
public class Mapper
{
private object MapObject(object source, object dest)
{
var destProperties = dest.GetType()
.GetProperties(BindingFlags.Instance | BindingFlags.Public)
.Where(x => x.CanWrite)
.ToArray();

foreach (var destProp in destProperties)
{
var sourceProp = source.GetType()
.GetProperties(BindingFlags.Instance | BindingFlags.Public)
.Where(p => p.Name == destProp.Name)
.FirstOrDefault();

if (sourceProp != null)
{
var sourceValue = sourceProp.GetMethod.Invoke(source, new object[0]);
if (sourceValue == null)
{
throw new ArgumentException(ExceptionUtils.NullableSourceValueGetMethod);
}

if (ReflectionUtils.IsPrimitive(sourceValue.GetType()))
{
destProp.SetValue(dest, sourceProp.GetValue(source, null), null);
continue;
}

if (ReflectionUtils.IsGenericCollection(sourceValue.GetType()))
{
if (ReflectionUtils.IsPrimitive(sourceValue.GetType().GetGenericArguments()[0]))
{
var destinationCollection = sourceValue;

destProp.SetMethod.Invoke(dest, new[] { destinationCollection });
}
else
{
var destColl = destProp.GetMethod.Invoke(dest, new object[0]);
var destType = destColl.GetType().GetGenericArguments()[0];

foreach (var destP in (IEnumerable)sourceValue)
{
((IList)destColl).Add(this.CreateMappedObject(destP, destType));
}
}
}
else if (ReflectionUtils.IsNonGenericCollection(sourceValue.GetType()))
{
var destColl = (IList)Activator.CreateInstance(destProp.PropertyType, new object[] { ((object[])sourceValue).Length });

for (int i = 0; i < ((object[])sourceValue).Length; i++)
{
destColl[i] = this.CreateMappedObject(((object[])sourceValue)[i], destProp.PropertyType.GetElementType());
}

destProp.SetValue(dest, destColl);
}
else
{
destProp.SetValue(dest, this.CreateMappedObject(sourceProp.GetValue(source), destProp.PropertyType));
}
}
}

return dest;
}

public TDest CreateMappedObject<TDest>(object source)
{
if (source == null)
{
throw new ArgumentException(ExceptionUtils.NullSource);
}

var dest = Activator.CreateInstance(typeof(TDest));

return (TDest)MapObject(source, dest);
}

private object CreateMappedObject(object source, Type ret)
{
if (source == null || ret == null)
{
throw new ArgumentException(ExceptionUtils.NullSourceValueOrReturnType);
}

var dest = Activator.CreateInstance(ret);

return MapObject(source, dest);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace CustomAutoMapper
{
public class MapperConfiguration
{
public Mapper Mapper { get; set; }

public MapperConfiguration CreateMap()
{
this.Mapper = new Mapper();
return this;
}
}
}
16 changes: 16 additions & 0 deletions 08.Workshop - CustomAutoMapper/CustomAutoMapper/Person.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace CustomAutoMapper
{
public class Person
{
public string Name { get; set; }

public int Age { get; set; }

public List<string> Courses { get; set; } = new List<string>();

}
}
23 changes: 23 additions & 0 deletions 08.Workshop - CustomAutoMapper/CustomAutoMapper/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;

namespace CustomAutoMapper
{
class Program
{
static void Main()
{
var mapper = new Mapper();

var person = new Person()
{
Name = "Asan",
Age = 20,
Courses = new List<string>() { "c#", "js" }
};

var student = mapper.CreateMappedObject<Student>(person);
Console.WriteLine();
}
}
}
68 changes: 68 additions & 0 deletions 08.Workshop - CustomAutoMapper/CustomAutoMapper/ReflectionUtils.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;

namespace CustomAutoMapper
{
public class ReflectionUtils
{
private static readonly HashSet<string> types = new HashSet<string>()
{
typeof(int).ToString(),
typeof(string).ToString(),
typeof(decimal).ToString(),
typeof(double).ToString(),
typeof(long).ToString(),
typeof(ulong).ToString(),
typeof(DateTime).ToString(),
typeof(Guid).ToString(),
typeof(int[]).ToString(),
typeof(string[]).ToString(),
typeof(decimal[]).ToString(),
typeof(double[]).ToString(),
typeof(long[]).ToString(),
typeof(ulong[]).ToString(),
typeof(DateTime[]).ToString(),
typeof(Guid[]).ToString(),
"System.Single",
"System.Single[]",

};

public static bool IsPrimitive(Type type)
{
return types.Contains(type.FullName) || type.IsPrimitive
|| IsNullable(type) && IsPrimitive(Nullable.GetUnderlyingType(type))
|| type.IsEnum;
}

public static bool IsGenericCollection(Type type)
{
return (type.IsGenericType && (
type.GetGenericTypeDefinition() == typeof(List<>)
||
type.GetGenericTypeDefinition() == typeof(ICollection<>)
||
type.GetGenericTypeDefinition() == typeof(IEnumerable<>)
||
type.GetGenericTypeDefinition() == typeof(IList<>)))
||
typeof(IList<>).IsAssignableFrom(type)
||
typeof(HashSet<>).IsAssignableFrom(type);
}

public static bool IsNonGenericCollection(Type type)
{
return type.IsArray ||
type == typeof(ArrayList) ||
typeof(IList).IsAssignableFrom(type);
}

private static bool IsNullable(Type type)
{
return type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>);
}
}
}
15 changes: 15 additions & 0 deletions 08.Workshop - CustomAutoMapper/CustomAutoMapper/Student.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace CustomAutoMapper
{
public class Student
{
public string Name { get; set; }

public int Age { get; set; }

public List<string> Courses { get; set; } = new List<string>();
}
}

0 comments on commit 6385fee

Please sign in to comment.