tools/AutoMapper/Profile.cs (155 lines of code) (raw):

using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Runtime.CompilerServices; using AutoMapper.Configuration; using AutoMapper.Configuration.Conventions; using AutoMapper.Mappers; namespace AutoMapper { /// <summary> /// Provides a named configuration for maps. Naming conventions become scoped per profile. /// </summary> public abstract class Profile : IProfileExpression, IProfileConfiguration { private readonly List<Action<PropertyMap, IMemberConfigurationExpression>> _allPropertyMapActions = new List<Action<PropertyMap, IMemberConfigurationExpression>>(); private readonly List<Action<TypeMap, IMappingExpression>> _allTypeMapActions = new List<Action<TypeMap, IMappingExpression>>(); private readonly List<string> _globalIgnore = new List<string>(); private readonly IList<IMemberConfiguration> _memberConfigurations = new List<IMemberConfiguration>(); private readonly List<ITypeMapConfiguration> _openTypeMapConfigs = new List<ITypeMapConfiguration>(); private readonly List<MethodInfo> _sourceExtensionMethods = new List<MethodInfo>(); private readonly IList<ConditionalObjectMapper> _typeConfigurations = new List<ConditionalObjectMapper>(); private readonly List<ITypeMapConfiguration> _typeMapConfigs = new List<ITypeMapConfiguration>(); private readonly List<ValueTransformerConfiguration> _valueTransformerConfigs = new List<ValueTransformerConfiguration>(); protected Profile(string profileName) : this() => ProfileName = profileName; protected Profile() { ProfileName = GetType().FullName; AddMemberConfiguration() .AddMember<NameSplitMember>() .AddName<PrePostfixName>(_ => _.AddStrings(p => p.Prefixes, "Get")); SourceMemberNamingConvention = new PascalCaseNamingConvention(); DestinationMemberNamingConvention = new PascalCaseNamingConvention(); } protected Profile(string profileName, Action<IProfileExpression> configurationAction) : this(profileName) { configurationAction(this); } public IMemberConfiguration DefaultMemberConfig => _memberConfigurations.First(); public bool? ConstructorMappingEnabled { get; private set; } public bool? CreateMissingTypeMaps { get; set; } public bool? ValidateInlineMaps { get; set; } IEnumerable<Action<PropertyMap, IMemberConfigurationExpression>> IProfileConfiguration.AllPropertyMapActions => _allPropertyMapActions; IEnumerable<Action<TypeMap, IMappingExpression>> IProfileConfiguration.AllTypeMapActions => _allTypeMapActions; IEnumerable<string> IProfileConfiguration.GlobalIgnores => _globalIgnore; IEnumerable<IMemberConfiguration> IProfileConfiguration.MemberConfigurations => _memberConfigurations; IEnumerable<MethodInfo> IProfileConfiguration.SourceExtensionMethods => _sourceExtensionMethods; IEnumerable<IConditionalObjectMapper> IProfileConfiguration.TypeConfigurations => _typeConfigurations; IEnumerable<ITypeMapConfiguration> IProfileConfiguration.TypeMapConfigs => _typeMapConfigs; IEnumerable<ITypeMapConfiguration> IProfileConfiguration.OpenTypeMapConfigs => _openTypeMapConfigs; IEnumerable<ValueTransformerConfiguration> IProfileConfiguration.ValueTransformers => _valueTransformerConfigs; public virtual string ProfileName { get; } public bool? AllowNullDestinationValues { get; set; } public bool? AllowNullCollections { get; set; } public bool? EnableNullPropagationForQueryMapping { get; set; } public Func<PropertyInfo, bool> ShouldMapProperty { get; set; } public Func<FieldInfo, bool> ShouldMapField { get; set; } public INamingConvention SourceMemberNamingConvention { get; set; } public INamingConvention DestinationMemberNamingConvention { get; set; } public IList<ValueTransformerConfiguration> ValueTransformers => _valueTransformerConfigs; public void DisableConstructorMapping() { ConstructorMappingEnabled = false; } public void ForAllMaps(Action<TypeMap, IMappingExpression> configuration) { _allTypeMapActions.Add(configuration); } public void ForAllPropertyMaps(Func<PropertyMap, bool> condition, Action<PropertyMap, IMemberConfigurationExpression> configuration) { _allPropertyMapActions.Add((pm, cfg) => { if (condition(pm)) configuration(pm, cfg); }); } public IMappingExpression<TSource, TDestination> CreateMap<TSource, TDestination>() => CreateMap<TSource, TDestination>(MemberList.Destination); public IMappingExpression<TSource, TDestination> CreateMap<TSource, TDestination>(MemberList memberList) => CreateMappingExpression<TSource, TDestination>(memberList); public IMappingExpression CreateMap(Type sourceType, Type destinationType) => CreateMap(sourceType, destinationType, MemberList.Destination); public IMappingExpression CreateMap(Type sourceType, Type destinationType, MemberList memberList) { var map = new MappingExpression(new TypePair(sourceType, destinationType), memberList); _typeMapConfigs.Add(map); if (sourceType.IsGenericTypeDefinition() || destinationType.IsGenericTypeDefinition()) _openTypeMapConfigs.Add(map); return map; } public void ClearPrefixes() { DefaultMemberConfig.AddName<PrePostfixName>(_ => _.Prefixes.Clear()); } public void RecognizeAlias(string original, string alias) { DefaultMemberConfig.AddName<ReplaceName>(_ => _.AddReplace(original, alias)); } public void ReplaceMemberName(string original, string newValue) { DefaultMemberConfig.AddName<ReplaceName>(_ => _.AddReplace(original, newValue)); } public void RecognizePrefixes(params string[] prefixes) { DefaultMemberConfig.AddName<PrePostfixName>(_ => _.AddStrings(p => p.Prefixes, prefixes)); } public void RecognizePostfixes(params string[] postfixes) { DefaultMemberConfig.AddName<PrePostfixName>(_ => _.AddStrings(p => p.Postfixes, postfixes)); } public void RecognizeDestinationPrefixes(params string[] prefixes) { DefaultMemberConfig.AddName<PrePostfixName>(_ => _.AddStrings(p => p.DestinationPrefixes, prefixes)); } public void RecognizeDestinationPostfixes(params string[] postfixes) { DefaultMemberConfig.AddName<PrePostfixName>(_ => _.AddStrings(p => p.DestinationPostfixes, postfixes)); } public void AddGlobalIgnore(string propertyNameStartingWith) { _globalIgnore.Add(propertyNameStartingWith); } public IMemberConfiguration AddMemberConfiguration() { var condition = new MemberConfiguration(); _memberConfigurations.Add(condition); return condition; } public IConditionalObjectMapper AddConditionalObjectMapper() { var condition = new ConditionalObjectMapper(); _typeConfigurations.Add(condition); return condition; } public void IncludeSourceExtensionMethods(Type type) { _sourceExtensionMethods.AddRange( type.GetDeclaredMethods() .Where( m => m.IsStatic && m.IsDefined(typeof(ExtensionAttribute), false) && m.GetParameters().Length == 1)); } private IMappingExpression<TSource, TDestination> CreateMappingExpression<TSource, TDestination>( MemberList memberList) { var mappingExp = new MappingExpression<TSource, TDestination>(memberList); _typeMapConfigs.Add(mappingExp); return mappingExp; } } }