diff --git a/Volo.Abp.sln b/Volo.Abp.sln
index ce61195bed..8f561b22f5 100644
--- a/Volo.Abp.sln
+++ b/Volo.Abp.sln
@@ -1,7 +1,7 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
-VisualStudioVersion = 15.0.26228.9
+VisualStudioVersion = 15.0.26430.6
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}"
EndProject
@@ -106,13 +106,15 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.Identity.Web", "sr
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.Identity.HttpApi.Client", "src\Volo.Abp.Identity.HttpApi.Client\Volo.Abp.Identity.HttpApi.Client.csproj", "{00B240B6-EC44-461A-9578-EF4F1BE9C688}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Autofac", "src\Volo.Abp.Autofac\Volo.Abp.Autofac.csproj", "{CECE1288-B5A1-4A6B-BEE0-331861F94983}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.Autofac", "src\Volo.Abp.Autofac\Volo.Abp.Autofac.csproj", "{CECE1288-B5A1-4A6B-BEE0-331861F94983}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Castle.Core", "src\Volo.Abp.Castle.Core\Volo.Abp.Castle.Core.csproj", "{053F7446-0545-482E-9F29-9C96B926966C}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.Castle.Core", "src\Volo.Abp.Castle.Core\Volo.Abp.Castle.Core.csproj", "{053F7446-0545-482E-9F29-9C96B926966C}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Autofac.Tests", "test\Volo.Abp.Autofac.Tests\Volo.Abp.Autofac.Tests.csproj", "{D8BE64D2-BD83-40F5-9783-D7FDDF668C45}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.Autofac.Tests", "test\Volo.Abp.Autofac.Tests\Volo.Abp.Autofac.Tests.csproj", "{D8BE64D2-BD83-40F5-9783-D7FDDF668C45}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Castle.Core.Tests", "test\Volo.Abp.Castle.Core.Tests\Volo.Abp.Castle.Core.Tests.csproj", "{CE12E5C2-7B3E-4637-B6A3-274BB5C3DE16}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.Castle.Core.Tests", "test\Volo.Abp.Castle.Core.Tests\Volo.Abp.Castle.Core.Tests.csproj", "{CE12E5C2-7B3E-4637-B6A3-274BB5C3DE16}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.AutoMapper", "src\Volo.Abp.AutoMapper\Volo.Abp.AutoMapper.csproj", "{D2F3594F-E2B9-4338-A022-F00C4E9A14C3}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -276,6 +278,10 @@ Global
{CE12E5C2-7B3E-4637-B6A3-274BB5C3DE16}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CE12E5C2-7B3E-4637-B6A3-274BB5C3DE16}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CE12E5C2-7B3E-4637-B6A3-274BB5C3DE16}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D2F3594F-E2B9-4338-A022-F00C4E9A14C3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D2F3594F-E2B9-4338-A022-F00C4E9A14C3}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D2F3594F-E2B9-4338-A022-F00C4E9A14C3}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D2F3594F-E2B9-4338-A022-F00C4E9A14C3}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -329,5 +335,6 @@ Global
{053F7446-0545-482E-9F29-9C96B926966C} = {4C753F64-0C93-4D65-96C2-A40893AFC1E8}
{D8BE64D2-BD83-40F5-9783-D7FDDF668C45} = {37087D1B-3693-4E96-983D-A69F210BDE53}
{CE12E5C2-7B3E-4637-B6A3-274BB5C3DE16} = {37087D1B-3693-4E96-983D-A69F210BDE53}
+ {D2F3594F-E2B9-4338-A022-F00C4E9A14C3} = {4C753F64-0C93-4D65-96C2-A40893AFC1E8}
EndGlobalSection
EndGlobal
diff --git a/src/Volo.Abp.AutoMapper/Volo.Abp.AutoMapper.csproj b/src/Volo.Abp.AutoMapper/Volo.Abp.AutoMapper.csproj
new file mode 100644
index 0000000000..6678671ddc
--- /dev/null
+++ b/src/Volo.Abp.AutoMapper/Volo.Abp.AutoMapper.csproj
@@ -0,0 +1,23 @@
+
+
+
+ netstandard1.6
+ Volo.Abp.AutoMapper
+ Volo.Abp.AutoMapper
+ 1.6.1
+ $(PackageTargetFallback);dnxcore50
+ false
+ false
+ false
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Volo.Abp.AutoMapper/Volo/Abp/AutoMapper/AbpAutoMapperConfiguration.cs b/src/Volo.Abp.AutoMapper/Volo/Abp/AutoMapper/AbpAutoMapperConfiguration.cs
new file mode 100644
index 0000000000..2665e5c950
--- /dev/null
+++ b/src/Volo.Abp.AutoMapper/Volo/Abp/AutoMapper/AbpAutoMapperConfiguration.cs
@@ -0,0 +1,19 @@
+using System;
+using System.Collections.Generic;
+using AutoMapper;
+
+namespace Volo.Abp.AutoMapper
+{
+ public class AbpAutoMapperConfiguration : IAbpAutoMapperConfiguration
+ {
+ public List> Configurators { get; }
+
+ public bool UseStaticMapper { get; set; }
+
+ public AbpAutoMapperConfiguration()
+ {
+ UseStaticMapper = true;
+ Configurators = new List>();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Volo.Abp.AutoMapper/Volo/Abp/AutoMapper/AbpAutoMapperModule.cs b/src/Volo.Abp.AutoMapper/Volo/Abp/AutoMapper/AbpAutoMapperModule.cs
new file mode 100644
index 0000000000..c8eb26fc57
--- /dev/null
+++ b/src/Volo.Abp.AutoMapper/Volo/Abp/AutoMapper/AbpAutoMapperModule.cs
@@ -0,0 +1,98 @@
+using System;
+using AutoMapper;
+using Microsoft.Extensions.Logging;
+using Volo.Abp.Modularity;
+
+namespace Volo.Abp.AutoMapper
+{
+ public class AbpAutoMapperModule : AbpModule
+ {
+ //private readonly ITypeFinder _typeFinder;
+
+ //private static volatile bool _createdMappingsBefore;
+ //private static readonly object SyncObj = new object();
+
+ //public AbpAutoMapperModule(ITypeFinder typeFinder)
+ //{
+ // _typeFinder = typeFinder;
+ //}
+
+ //public override void PreInitialize()
+ //{
+ // IocManager.Register();
+
+ // Configuration.ReplaceService();
+
+ // Configuration.Modules.AbpAutoMapper().Configurators.Add(CreateCoreMappings);
+ //}
+
+ //public override void PostInitialize()
+ //{
+ // CreateMappings();
+ //}
+
+ //private void CreateMappings()
+ //{
+ // lock (SyncObj)
+ // {
+ // Action configurer = configuration =>
+ // {
+ // FindAndAutoMapTypes(configuration);
+ // foreach (var configurator in Configuration.Modules.AbpAutoMapper().Configurators)
+ // {
+ // configurator(configuration);
+ // }
+ // };
+
+ // if (Configuration.Modules.AbpAutoMapper().UseStaticMapper)
+ // {
+ // //We should prevent duplicate mapping in an application, since Mapper is static.
+ // if (!_createdMappingsBefore)
+ // {
+ // Mapper.Initialize(configurer);
+ // _createdMappingsBefore = true;
+ // }
+
+ // IocManager.IocContainer.Register(
+ // Component.For().Instance(Mapper.Instance).LifestyleSingleton()
+ // );
+ // }
+ // else
+ // {
+ // var config = new MapperConfiguration(configurer);
+ // IocManager.IocContainer.Register(
+ // Component.For().Instance(config.CreateMapper()).LifestyleSingleton()
+ // );
+ // }
+ // }
+ //}
+
+ //private void FindAndAutoMapTypes(IMapperConfigurationExpression configuration)
+ //{
+ // var types = _typeFinder.Find(type =>
+ // {
+ // var typeInfo = type.GetTypeInfo();
+ // return typeInfo.IsDefined(typeof(AutoMapAttribute)) ||
+ // typeInfo.IsDefined(typeof(AutoMapFromAttribute)) ||
+ // typeInfo.IsDefined(typeof(AutoMapToAttribute));
+ // }
+ // );
+
+ // Logger<>.DebugFormat("Found {0} classes define auto mapping attributes", types.Length);
+
+ // foreach (var type in types)
+ // {
+ // Logger<>.Debug(type.FullName);
+ // configuration.CreateAutoAttributeMaps(type);
+ // }
+ //}
+
+ //private void CreateCoreMappings(IMapperConfigurationExpression configuration)
+ //{
+ // var localizationContext = IocManager.Resolve();
+
+ // configuration.CreateMap().ConvertUsing(ls => ls?.Localize(localizationContext));
+ // configuration.CreateMap().ConvertUsing(ls => ls == null ? null : localizationContext.LocalizationManager.GetString(ls));
+ //}
+ }
+}
diff --git a/src/Volo.Abp.AutoMapper/Volo/Abp/AutoMapper/AutoMapAttribute.cs b/src/Volo.Abp.AutoMapper/Volo/Abp/AutoMapper/AutoMapAttribute.cs
new file mode 100644
index 0000000000..f5284776fc
--- /dev/null
+++ b/src/Volo.Abp.AutoMapper/Volo/Abp/AutoMapper/AutoMapAttribute.cs
@@ -0,0 +1,29 @@
+using System;
+using AutoMapper;
+using Volo.ExtensionMethods.Collections.Generic;
+
+namespace Volo.Abp.AutoMapper
+{
+ public class AutoMapAttribute : AutoMapAttributeBase
+ {
+ public AutoMapAttribute(params Type[] targetTypes)
+ : base(targetTypes)
+ {
+
+ }
+
+ public override void CreateMap(IMapperConfigurationExpression configuration, Type type)
+ {
+ if (TargetTypes.IsNullOrEmpty())
+ {
+ return;
+ }
+
+ foreach (var targetType in TargetTypes)
+ {
+ configuration.CreateMap(type, targetType, MemberList.Source);
+ configuration.CreateMap(targetType, type, MemberList.Destination);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Volo.Abp.AutoMapper/Volo/Abp/AutoMapper/AutoMapAttributeBase.cs b/src/Volo.Abp.AutoMapper/Volo/Abp/AutoMapper/AutoMapAttributeBase.cs
new file mode 100644
index 0000000000..5756347380
--- /dev/null
+++ b/src/Volo.Abp.AutoMapper/Volo/Abp/AutoMapper/AutoMapAttributeBase.cs
@@ -0,0 +1,17 @@
+using System;
+using AutoMapper;
+
+namespace Volo.Abp.AutoMapper
+{
+ public abstract class AutoMapAttributeBase : Attribute
+ {
+ public Type[] TargetTypes { get; }
+
+ protected AutoMapAttributeBase(params Type[] targetTypes)
+ {
+ TargetTypes = targetTypes;
+ }
+
+ public abstract void CreateMap(IMapperConfigurationExpression configuration, Type type);
+ }
+}
\ No newline at end of file
diff --git a/src/Volo.Abp.AutoMapper/Volo/Abp/AutoMapper/AutoMapExtensions.cs b/src/Volo.Abp.AutoMapper/Volo/Abp/AutoMapper/AutoMapExtensions.cs
new file mode 100644
index 0000000000..32c0ad93fa
--- /dev/null
+++ b/src/Volo.Abp.AutoMapper/Volo/Abp/AutoMapper/AutoMapExtensions.cs
@@ -0,0 +1,32 @@
+using AutoMapper;
+
+namespace Volo.Abp.AutoMapper
+{
+ public static class AutoMapExtensions
+ {
+ ///
+ /// Converts an object to another using AutoMapper library. Creates a new object of .
+ /// There must be a mapping between objects before calling this method.
+ ///
+ /// Type of the destination object
+ /// Source object
+ public static TDestination MapTo(this object source)
+ {
+ return Mapper.Map(source);
+ }
+
+ ///
+ /// Execute a mapping from the source object to the existing destination object
+ /// There must be a mapping between objects before calling this method.
+ ///
+ /// Source type
+ /// Destination type
+ /// Source object
+ /// Destination object
+ ///
+ public static TDestination MapTo(this TSource source, TDestination destination)
+ {
+ return Mapper.Map(source, destination);
+ }
+ }
+}
diff --git a/src/Volo.Abp.AutoMapper/Volo/Abp/AutoMapper/AutoMapFromAttribute.cs b/src/Volo.Abp.AutoMapper/Volo/Abp/AutoMapper/AutoMapFromAttribute.cs
new file mode 100644
index 0000000000..9d0c765559
--- /dev/null
+++ b/src/Volo.Abp.AutoMapper/Volo/Abp/AutoMapper/AutoMapFromAttribute.cs
@@ -0,0 +1,36 @@
+using System;
+using AutoMapper;
+using Volo.ExtensionMethods.Collections.Generic;
+
+namespace Volo.Abp.AutoMapper
+{
+ public class AutoMapFromAttribute : AutoMapAttributeBase
+ {
+ public MemberList MemberList { get; set; } = MemberList.Destination;
+
+ public AutoMapFromAttribute(params Type[] targetTypes)
+ : base(targetTypes)
+ {
+
+ }
+
+ public AutoMapFromAttribute(MemberList memberList, params Type[] targetTypes)
+ : this(targetTypes)
+ {
+ MemberList = memberList;
+ }
+
+ public override void CreateMap(IMapperConfigurationExpression configuration, Type type)
+ {
+ if (TargetTypes.IsNullOrEmpty())
+ {
+ return;
+ }
+
+ foreach (var targetType in TargetTypes)
+ {
+ configuration.CreateMap(targetType, type, MemberList);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Volo.Abp.AutoMapper/Volo/Abp/AutoMapper/AutoMapToAttribute.cs b/src/Volo.Abp.AutoMapper/Volo/Abp/AutoMapper/AutoMapToAttribute.cs
new file mode 100644
index 0000000000..a0f3e4e26f
--- /dev/null
+++ b/src/Volo.Abp.AutoMapper/Volo/Abp/AutoMapper/AutoMapToAttribute.cs
@@ -0,0 +1,36 @@
+using System;
+using AutoMapper;
+using Volo.ExtensionMethods.Collections.Generic;
+
+namespace Volo.Abp.AutoMapper
+{
+ public class AutoMapToAttribute : AutoMapAttributeBase
+ {
+ public MemberList MemberList { get; set; } = MemberList.Source;
+
+ public AutoMapToAttribute(params Type[] targetTypes)
+ : base(targetTypes)
+ {
+
+ }
+
+ public AutoMapToAttribute(MemberList memberList, params Type[] targetTypes)
+ : this(targetTypes)
+ {
+ MemberList = memberList;
+ }
+
+ public override void CreateMap(IMapperConfigurationExpression configuration, Type type)
+ {
+ if (TargetTypes.IsNullOrEmpty())
+ {
+ return;
+ }
+
+ foreach (var targetType in TargetTypes)
+ {
+ configuration.CreateMap(type, targetType, MemberList);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Volo.Abp.AutoMapper/Volo/Abp/AutoMapper/AutoMapperConfigurationExtensions.cs b/src/Volo.Abp.AutoMapper/Volo/Abp/AutoMapper/AutoMapperConfigurationExtensions.cs
new file mode 100644
index 0000000000..579e5181d1
--- /dev/null
+++ b/src/Volo.Abp.AutoMapper/Volo/Abp/AutoMapper/AutoMapperConfigurationExtensions.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Reflection;
+using AutoMapper;
+
+namespace Volo.Abp.AutoMapper
+{
+ internal static class AutoMapperConfigurationExtensions
+ {
+ public static void CreateAutoAttributeMaps(this IMapperConfigurationExpression configuration, Type type)
+ {
+ foreach (var autoMapAttribute in type.GetTypeInfo().GetCustomAttributes())
+ {
+ autoMapAttribute.CreateMap(configuration, type);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Volo.Abp.AutoMapper/Volo/Abp/AutoMapper/AutoMapperObjectMapper.cs b/src/Volo.Abp.AutoMapper/Volo/Abp/AutoMapper/AutoMapperObjectMapper.cs
new file mode 100644
index 0000000000..dbb41da797
--- /dev/null
+++ b/src/Volo.Abp.AutoMapper/Volo/Abp/AutoMapper/AutoMapperObjectMapper.cs
@@ -0,0 +1,24 @@
+using AutoMapper;
+
+namespace Volo.Abp.AutoMapper
+{
+ public class AutoMapperObjectMapper : Volo.Abp.ObjectMapping.IObjectMapper
+ {
+ private readonly IMapper _mapper;
+
+ public AutoMapperObjectMapper(IMapper mapper)
+ {
+ _mapper = mapper;
+ }
+
+ public TDestination Map(object source)
+ {
+ return _mapper.Map(source);
+ }
+
+ public TDestination Map(TSource source, TDestination destination)
+ {
+ return _mapper.Map(source, destination);
+ }
+ }
+}
diff --git a/src/Volo.Abp.AutoMapper/Volo/Abp/AutoMapper/IAbpAutoMapperConfiguration.cs b/src/Volo.Abp.AutoMapper/Volo/Abp/AutoMapper/IAbpAutoMapperConfiguration.cs
new file mode 100644
index 0000000000..f5e660a09f
--- /dev/null
+++ b/src/Volo.Abp.AutoMapper/Volo/Abp/AutoMapper/IAbpAutoMapperConfiguration.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using AutoMapper;
+
+namespace Volo.Abp.AutoMapper
+{
+ public interface IAbpAutoMapperConfiguration
+ {
+ List> Configurators { get; }
+
+ ///
+ /// Use static .
+ /// Default: true.
+ ///
+ bool UseStaticMapper { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/src/Volo.Abp/Volo/Abp/ObjectMapping/IObjectMapper.cs b/src/Volo.Abp/Volo/Abp/ObjectMapping/IObjectMapper.cs
new file mode 100644
index 0000000000..70212b1ff4
--- /dev/null
+++ b/src/Volo.Abp/Volo/Abp/ObjectMapping/IObjectMapper.cs
@@ -0,0 +1,25 @@
+namespace Volo.Abp.ObjectMapping
+{
+ ///
+ /// Defines a simple interface to map objects.
+ ///
+ public interface IObjectMapper
+ {
+ ///
+ /// Converts an object to another. Creates a new object of .
+ ///
+ /// Type of the destination object
+ /// Source object
+ TDestination Map(object source);
+
+ ///
+ /// Execute a mapping from the source object to the existing destination object
+ ///
+ /// Source type
+ /// Destination type
+ /// Source object
+ /// Destination object
+ /// Returns the same object after mapping operation
+ TDestination Map(TSource source, TDestination destination);
+ }
+}
diff --git a/src/Volo.Abp/Volo/Abp/ObjectMapping/NotImplementedObjectMapper.cs b/src/Volo.Abp/Volo/Abp/ObjectMapping/NotImplementedObjectMapper.cs
new file mode 100644
index 0000000000..064991e4d3
--- /dev/null
+++ b/src/Volo.Abp/Volo/Abp/ObjectMapping/NotImplementedObjectMapper.cs
@@ -0,0 +1,23 @@
+using System;
+using Volo.DependencyInjection;
+
+namespace Volo.Abp.ObjectMapping
+{
+ public sealed class NotImplementedObjectMapper : IObjectMapper, ISingletonDependency
+ {
+ ///
+ /// Singleton instance.
+ ///
+ public static NotImplementedObjectMapper Instance { get; } = new NotImplementedObjectMapper();
+
+ public TDestination Map(object source)
+ {
+ throw new NotImplementedException("Abp.ObjectMapping.IObjectMapper should be implemented in order to map objects.");
+ }
+
+ public TDestination Map(TSource source, TDestination destination)
+ {
+ throw new NotImplementedException("Abp.ObjectMapping.IObjectMapper should be implemented in order to map objects.");
+ }
+ }
+}
\ No newline at end of file