首页 文章

如何在ASP.NET Core中设置Automapper

提问于
浏览
137

我是.NET的新手,我决定解决.NET Core而不是学习"old ways" . 我找到了一篇关于setting up AutoMapper for .NET Core here的详细文章,但新手有更简单的演练吗?

8 回答

  • 0

    我想到了!这是详细信息:

    • 通过NuGet将主AutoMapper软件包添加到您的解决方案中 .

    • 通过NuGet将AutoMapper依赖关系注入包添加到您的解决方案中 .

    • 为映射配置文件创建新类 . (我在主解决方案目录中创建了一个名为 MappingProfile.cs 的类,并添加以下代码 . )我将使用 UserUserDto 对象作为示例 .

    public class MappingProfile : Profile {
        public MappingProfile() {
            // Add as many of these lines as you need to map your objects
            CreateMap<User, UserDto>();
            CreateMap<UserDto, User>();
        }
    }
    
    • 然后在 Startup.cs 中添加AutoMapperConfiguration,如下所示:
    public void ConfigureServices(IServiceCollection services) {
        // .... Ignore code before this
    
       // Auto Mapper Configurations
        var mappingConfig = new MapperConfiguration(mc =>
        {
            mc.AddProfile(new MappingProfile());
        });
    
        IMapper mapper = mappingConfig.CreateMapper();
        services.AddSingleton(mapper);
    
        services.AddMvc();
    
    }
    
    • 要在代码中调用映射对象,请执行以下操作:
    public class UserController : Controller {
    
        // Create a field to store the mapper object
        private readonly IMapper _mapper;
    
        // Assign the object in the constructor for dependency injection
        public UserController(IMapper mapper) {
            _mapper = mapper;
        }
    
        public async Task<IActionResult> Edit(string id) {
    
            // Instantiate source object
            // (Get it from the database or whatever your code calls for)
            var user = await _context.Users
                .SingleOrDefaultAsync(u => u.Id == id);
    
            // Instantiate the mapped data transfer object
            // using the mapper you stored in the private field.
            // The type of the source object is the first type argument
            // and the type of the destination is the second.
            // Pass the source object you just instantiated above
            // as the argument to the _mapper.Map<>() method.
            var model = _mapper.Map<UserDto>(user);
    
            // .... Do whatever you want after that!
        }
    }
    

    我希望这有助于有人开始使用ASP.NET Core!我欢迎任何反馈或批评,因为我还是.NET世界的新手!

  • 0

    theutz'这里的答案非常好,我只想补充一点:

    如果您让映射配置文件继承自 MapperConfigurationExpression 而不是 Profile ,则可以非常简单地添加测试以验证映射设置,这总是很方便:

    [Fact]
    public void MappingProfile_VerifyMappings()
    {
        var mappingProfile = new MappingProfile();
    
        var config = new MapperConfiguration(mappingProfile);
        var mapper = new Mapper(config);
    
        (mapper as IMapper).ConfigurationProvider.AssertConfigurationIsValid();
    }
    
  • 2

    我想扩展@theutz的答案 - 即这一行:

    // services.AddAutoMapper(typeof(Startup));  // <-- newer automapper version uses this signature.
    

    AutoMapper.Extensions.Microsoft.DependencyInjection版本3.2.0中存在一个错误(可能) . (我使用的是.NET Core 2.0)

    这是在this GitHub问题中解决的 . 如果您继承AutoMapper的Profile类的类存在于程序集之外的Startup类,那么如果您的AutoMapper注入如下所示,它们可能不会被注册:

    services.AddAutoMapper();
    

    除非您明确指定要搜索AutoMapper配置文件的程序集 .

    它可以在你的Startup.ConfigureServices中这样完成:

    services.AddAutoMapper(<assembies> or <type_in_assemblies>);
    

    其中"assemblies"和"type_in_assemblies"指向指定应用程序中的“类”类的程序集 . 例如:

    services.AddAutoMapper(typeof(ProfileInOtherAssembly), typeof(ProfileInYetAnotherAssembly));
    

    suppose (我强调这个词)由于遵循无参数overaload(来自GitHub的源代码)的实现:

    public static IServiceCollection AddAutoMapper(this IServiceCollection services)
    {
         return services.AddAutoMapper(null, AppDomain.CurrentDomain.GetAssemblies());
    }
    

    我们依赖于CLR已经包含了包含AutoMapper配置文件的JITed程序集,这些配置文件可能是或者可能不是真的,因为它们只在需要时进行jitted(在this StackOverflow问题中更多的deatils) .

  • 4

    我正在使用AutoMapper 6.1.1和asp.net Core 1.1.2 .

    首先,定义Automapper的Profile Class继承的Profile类 . 我创建了IProfile接口,它是空的,目的只是找到这种类的类 .

    public class UserProfile : Profile, IProfile
        {
            public UserProfile()
            {
                CreateMap<User, UserModel>();
                CreateMap<UserModel, User>();
            }
        }
    

    现在创建一个单独的类,例如Mappings

    public class Mappings
        {
         public static void RegisterMappings()
         {            
           var all =
           Assembly
              .GetEntryAssembly()
              .GetReferencedAssemblies()
              .Select(Assembly.Load)
              .SelectMany(x => x.DefinedTypes)
              .Where(type => typeof(IProfile).GetTypeInfo().IsAssignableFrom(type.AsType()));
    
                foreach (var ti in all)
                {
                    var t = ti.AsType();
                    if (t.Equals(typeof(IProfile)))
                    {
                        Mapper.Initialize(cfg =>
                        {
                            cfg.AddProfiles(t); // Initialise each Profile classe
                        });
                    }
                }         
            }
    
        }
    

    现在在Startup.cs文件的MVC Core web Project中,在构造函数中,调用Mapping类,它将在应用程序加载时初始化所有映射 .

    Mappings.RegisterMappings();
    
  • 23

    services.AddAutoMapper();对我不起作用 . (我使用的是Asp.Net Core 2.0)

    配置如下

    var config = new AutoMapper.MapperConfiguration(cfg =>
       {                 
           cfg.CreateMap<ClientCustomer, Models.Customer>();
       });
    

    初始化映射器IMapper mapper = config.CreateMapper();

    并将mapper对象作为singleton services.AddSingleton(mapper)添加到服务中;

    这样我就可以在控制器中添加DI

    private IMapper autoMapper = null;
    
      public VerifyController(IMapper mapper)
      {              
       autoMapper = mapper;  
      }
    

    我在我的行动方法中使用如下

    ClientCustomer customerObj = autoMapper.Map<ClientCustomer>(customer);
    
  • 353

    关于theutz的答案,没有必要在控制器构造函数中指定 IMapper mapper 参数 .

    你可以使用Mapper,因为它是代码任何地方的静态成员 .

    public class UserController : Controller {
       public someMethod()
       {
          Mapper.Map<User, UserDto>(user);
       }
    }
    
  • 0

    添加Arve Systad提到的测试内容 . 如果由于某种原因你和我一样想要维护theutz解决方案中提供的继承结构,你可以像这样设置MapperConfiguration:

    var mappingProfile = new MappingProfile();
    var config = new MapperConfiguration(cfg =>
    {
        cfg.AddProfile(mappingProfile);
    });
    var mapper = new Mapper(config);
    

    我是在NUnit中做到的 .

  • 8

    步骤将AutoMapper与ASP.NET Core一起使用 .

    步骤1.从NuGet包安装AutoMapper.Extensions.Microsoft.DependencyInjection .

    enter image description here

    步骤2.在解决方案中创建一个文件夹以使Mappings保持名称"Mappings" .

    enter image description here

    步骤3.添加Mapping文件夹后,我们添加了一个名为“ MappingProfile ”的类,这个名称可以是任何独特且易于理解的 .

    在本课程中,我们将维护所有映射 .

    enter image description here

    步骤4.在启动时初始化Mapper "ConfigureServices"

    在Startup Class中,我们需要初始化我们创建的Profile以及Register AutoMapper Service .

    Mapper.Initialize(cfg => cfg.AddProfile<MappingProfile>());
    
      services.AddAutoMapper();
    

    代码片段显示我们需要初始化和注册AutoMapper的ConfigureServices方法 .

    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }
    
        public IConfiguration Configuration { get; }
    
    
        public void ConfigureServices(IServiceCollection services)
        {
            services.Configure<CookiePolicyOptions>(options =>
            {
                // This lambda determines whether user consent for non-essential cookies is needed for a given request.
                options.CheckConsentNeeded = context => true;
                options.MinimumSameSitePolicy = SameSiteMode.None;
            });
    
    
            // Start Registering and Initializing AutoMapper
    
            Mapper.Initialize(cfg => cfg.AddProfile<MappingProfile>());
            services.AddAutoMapper();
    
            // End Registering and Initializing AutoMapper
    
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
    
        }}
    

    步骤5.获取输出 .

    要获取Mapped结果,我们需要调用AutoMapper.Mapper.Map并传递Proper Destination和Source .

    AutoMapper.Mapper.Map<Destination>(source);
    

    CodeSnippet

    [HttpPost]
        public void Post([FromBody] SchemeMasterViewModel schemeMaster)
        {
            if (ModelState.IsValid)
            {
                var mappedresult = AutoMapper.Mapper.Map<SchemeMaster>(schemeMaster);
            }
        }
    

相关问题