如何在AutoMapper中扫描和自动配置配置文件?

Woj*_*ski 22 .net structuremap profile automapper

有没有办法自动配置Automapper来扫描命名空间/程序集中的所有配置文件?我想要做的是从给定的程序集中过滤的给定程序集中将映射配置文件添加到AutoMapper,类似于StructureMap中的扫描约定:

    public static void Configure()
    {
        ObjectFactory.Initialize(x =>
            {
                // Scan Assembly
                x.Scan(
                    scanner =>
                    {
                        scanner.TheCallingAssembly();
                        scanner.Convention<MyCustomConvention>();
                        scanner.WithDefaultConventions();
                    });

                // Add Registries
                x.AddRegistry(new SomeRegistry());
            });

        Debug.WriteLine(ObjectFactory.WhatDoIHave());
    }

public class MyCustomConvention : IRegistrationConvention
{
    public void Process(Type type, Registry registry)
    {
        if (!type.CanBeCastTo(typeof(IMyType)))
        {
            return;
        }

        string name = type.Name.Replace("SomeRubishName", String.Empty);
        registry.AddType(typeof(IMyType), type, name);            
    }
Run Code Online (Sandbox Code Playgroud)

我试过使用SelfConfigure但找不到任何关于如何使用它来过滤配置文件的文档:

    public static void Configure()
    {
        Mapper.Initialize(x =>
                              {
                                  // My Custom profile
                                  x.AddProfile<MyMappingProfile>();

                                  // Scan Assembly
                                  x.SelfConfigure(Assembly.GetCallingAssembly());
                              });
    }
Run Code Online (Sandbox Code Playgroud)

另一个问题是我如何报告已经初始化的所有地图/配置文件(类似于StructureMap中的ObjectFactory.WhatDoIHave())?

Jas*_*ore 35

我在搜索时发现了这篇文章,但这就是我实现自动映射方案的方法:

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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

所以当我的应用程序启动时,我所说的就是

AutoMapperConfiguration.Configure(); 
Run Code Online (Sandbox Code Playgroud)

我的所有地图都已注册.

  • Arnis L - 只需更改configuration.AddProfile(Activator.CreateInstance(profile)作为Profile); to configuration.AddProfile(ServiceLocator.Current.GetInstance(profile)as Profile); (或类似的,显然它可能取决于你正在使用哪个IoC容器)来启用依赖注入.很好的答案. (2认同)

Mar*_*din 15

在最新版本的AutoMapper中,可以注册多个Profile扫描一个或多个程序集:

 Mapper.Initialize(x => x.AddProfiles(typeof(MyMappingProfile).Assembly));
Run Code Online (Sandbox Code Playgroud)

使用AutoMapper v.6.0.2.0进行测试


Ros*_*sco 12

在 AutoMapper 的第 9 版中,可以通过这种方式完成

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

如果您使用的是 ASP.NET Core,则有一个帮助程序扩展可以在 Startup.ConfigureServices 中注册所有配置文件

// UI project
services.AddAutoMapper(Assembly.GetExecutingAssembly());
Run Code Online (Sandbox Code Playgroud)

或者

// Another assembly that contains a type
services.AddAutoMapper(Assembly.GetAssembly(typeof(MyApp.SomeClass)));
Run Code Online (Sandbox Code Playgroud)


Jim*_*ard 7

是的,那太棒了......而且正是我正在为V2进行改造.扫描,注册,约定等

没有一个好的"我有什么"功能,但我认为这绝对值得添加.