How to scan and auto-configure profiles in AutoMapper?

后端 未结 8 611
花落未央
花落未央 2020-12-24 02:50

Is there any way to auto-configue Automapper to scan for all profiles in namespace/assembly? What I would like to do is to add mapping profiles to AutoMapper from given asse

相关标签:
8条回答
  • 2020-12-24 02:51

    In the latest versions of AutoMapper it's possible to register multiple Profile scanning one or more assemblies :

     Mapper.Initialize(x => x.AddProfiles(typeof(MyMappingProfile).Assembly));
    

    Tested with AutoMapper v. 6.0.2.0

    0 讨论(0)
  • 2020-12-24 02:56

    Yeah, that would be fantastic...and exactly what I'm overhauling for V2. Scanning, registration, conventions etc.

    There's not a good "What do I have" feature, but I think it would definitely be worth adding.

    0 讨论(0)
  • 2020-12-24 02:56

    In .NET Core:

        services.AddSingleton(this.CreateMapper());
        //...
        private IMapper CreateMapper()
                => new MapperConfiguration(config => config.AddMaps(Assembly.Load("Your.Project.App")))
                .CreateMapper();
    
    0 讨论(0)
  • 2020-12-24 02:57

    I found this post while searching as well, but this is how I implemented an auto mapping scheme:

    public class MyCustomMap : Profile
    {
        protected override void Configure()
        {
            CreateMap<MyCustomViewModel, MyCustomObject>()
                .ForMember(dest => dest.Phone,
                            opt => opt.MapFrom(
                            src => src.PhoneAreaCode + src.PhoneFirstThree + src.PhoneLastFour));
        }
    }
    
    public static class AutoMapperConfiguration
    {
        public static void Configure()
        {
            Mapper.Initialize(x => GetConfiguration(Mapper.Configuration));
        }
    
        private static void GetConfiguration(IConfiguration configuration)
        {
            var profiles = typeof(MyCustomMap).Assembly.GetTypes().Where(x => typeof(Profile).IsAssignableFrom(x));
            foreach (var profile in profiles)
            {
                configuration.AddProfile(Activator.CreateInstance(profile) as Profile);
            }
        }
    }
    

    So when my application starts, all I call is

    AutoMapperConfiguration.Configure(); 
    

    And all my maps are registered.

    0 讨论(0)
  • 2020-12-24 02:57

    I have it like this, don't know if it is the best way but it works very well on pretty large project.

    public class AutoMapperGlobalConfiguration : IGlobalConfiguration
        {
            private AutoMapper.IConfiguration _configuration;
    
            public AutoMapperGlobalConfiguration(IConfiguration configuration)
            {
                _configuration = configuration;
            }
    
            public void Configure()
            {
                //add all defined profiles
                var query = this.GetType().Assembly.GetExportedTypes()
                    .Where(x => x.CanBeCastTo(typeof(AutoMapper.Profile)));
    
                _configuration.RecognizePostfixes("Id");
    
                foreach (Type type in query)
                {
                    _configuration.AddProfile(ObjectFactory.GetInstance(type).As<Profile>());
                }
    
                //create maps for all Id2Entity converters
                MapAllEntities(_configuration);
    
               Mapper.AssertConfigurationIsValid();
            }
    
            private static void MapAllEntities(IProfileExpression configuration)
            {
                //get all types from the SR.Domain assembly and create maps that
                //convert int -> instance of the type using Id2EntityConverter
                var openType = typeof(Id2EntityConverter<>);
                var idType = typeof(int);
                var persistentEntties = typeof(SR.Domain.Policy.Entities.Bid).Assembly.GetTypes()
                   .Where(t => typeof(EntityBase).IsAssignableFrom(t))
                   .Select(t => new
                   {
                       EntityType = t,
                       ConverterType = openType.MakeGenericType(t)
                   });
                foreach (var e in persistentEntties)
                {
                    var map = configuration.CreateMap(idType, e.EntityType);
                    map.ConvertUsing(e.ConverterType);
                }
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-24 03:03

    In version 9 of AutoMapper it can be done this way

    var configuration = new MapperConfiguration(cfg =>
    {
        // Add all Profiles from the Assembly containing this Type
        cfg.AddMaps(typeof(MyApp.SomeClass));
    });
    

    If you are using ASP.NET Core there is a helper extension to register all Profiles in Startup.ConfigureServices

    // UI project
    services.AddAutoMapper(Assembly.GetExecutingAssembly());
    

    or

    // Another assembly that contains a type
    services.AddAutoMapper(Assembly.GetAssembly(typeof(MyApp.SomeClass)));
    
    0 讨论(0)
提交回复
热议问题