我是.NET的新手,所以我决定使用.NET Core,而不是学习“旧方法”。我在这里找到了有关为.NET Core设置AutoMapper的详细文章,但是对于新手来说,是否有更简单的演练?
我是.NET的新手,所以我决定使用.NET Core,而不是学习“旧方法”。我在这里找到了有关为.NET Core设置AutoMapper的详细文章,但是对于新手来说,是否有更简单的演练?
Answers:
我想到了!详细信息如下:
通过NuGet将AutoMapper依赖项注入程序包添加到您的解决方案中。
为映射配置文件创建一个新类。(我在主解决方案目录中创建了一个名为的类,MappingProfile.cs并添加了以下代码。)我将使用Userand UserDto对象作为示例。
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>();
    }
}然后在中添加AutoMapperConfiguration,Startup.cs如下所示:
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世界的新手!
Profile课程的位置
                    将AutoMapper与ASP.NET Core结合使用的步骤。
步骤1.从NuGet包中安装AutoMapper.Extensions.Microsoft.DependencyInjection。
步骤2.在解决方案中创建一个文件夹,以保留名称为“ Mappings”的映射。
步骤3.添加Mapping文件夹后,我们添加了一个名称为“ MappingProfile ” 的类,该名称可以唯一且易于理解。
在本课程中,我们将维护所有映射。
步骤4.在启动“ ConfigureServices”中初始化Mapper
在启动类中,我们需要初始化已创建的配置文件,并注册AutoMapper服务。
  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.获取输出。
要获得映射结果,我们需要调用AutoMapper.Mapper.Map并传递适当的目标和源。
AutoMapper.Mapper.Map<Destination>(source);代码片段
    [HttpPost]
    public void Post([FromBody] SchemeMasterViewModel schemeMaster)
    {
        if (ModelState.IsValid)
        {
            var mappedresult = AutoMapper.Mapper.Map<SchemeMaster>(schemeMaster);
        }
    }'Mapper' does not contain a definition for 'initialize'。我正在使用AutoMapper.Extensions.Microsoft.DependencyInjection7.0.0版
                    我想扩展@theutz的答案-即这一行:
// services.AddAutoMapper(typeof(Startup));  // <-- newer automapper version uses this signature.AutoMapper.Extensions.Microsoft.DependencyInjection版本3.2.0中有一个错误(可能是)。(我正在使用.NET Core 2.0)
这是在解决这个 GitHub的问题。如果您的继承自AutoMapper的Profile类的类在您的Startup类所在的程序集之外,而如果您的AutoMapper注入看起来像这样,则可能不会注册它们:
services.AddAutoMapper();除非您明确指定要搜索AutoMapper配置文件的程序集。
可以在Startup.ConfigureServices中这样做:
services.AddAutoMapper(<assembies> or <type_in_assemblies>);其中“程序集”和“ type_in_assemblies”指向在您的应用程序中指定了Profile类的程序集。例如:
services.AddAutoMapper(typeof(ProfileInOtherAssembly), typeof(ProfileInYetAnotherAssembly));我想(并强调这个词)是由于以下无参数重载的实现(来自GitHub的源代码):
public static IServiceCollection AddAutoMapper(this IServiceCollection services)
{
     return services.AddAutoMapper(null, AppDomain.CurrentDomain.GetAssemblies());
}我们依靠CLR已包含JIT程序集的AutoMapper概要文件进行了JIT组装,因为它们仅在需要时才被伪装(有关此问题,请参见StackOverflow问题中的更多信息)。
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();
}我通过.NET Core 2.2 / Automapper 8.1.1 w / Extensions.DI 6.1.1的这种方式(类似于上面的方式解决了该问题,但我觉得这是一个更干净的解决方案)。
创建MappingProfile.cs类,并使用Maps填充构造函数(我计划使用一个类来保存我的所有映射)
    public class MappingProfile : Profile
    {
        public MappingProfile()
        {
            CreateMap<Source, Dest>().ReverseMap();
        }
    }在Startup.cs中,添加以下内容以添加到DI(程序集arg用于保存您的映射配置的类,在我的情况下,它是MappingProfile类)。
//add automapper DI
services.AddAutoMapper(typeof(MappingProfile));
在Controller中,像使用其他任何DI对象一样使用它
    [Route("api/[controller]")]
    [ApiController]
    public class AnyController : ControllerBase
    {
        private readonly IMapper _mapper;
        public AnyController(IMapper mapper)
        {
            _mapper = mapper;
        }
        public IActionResult Get(int id)
        {
            var entity = repository.Get(id);
            var dto = _mapper.Map<Dest>(entity);
            return Ok(dto);
        }
    }
在我的Startup.cs(Core 2.2,Automapper 8.1.1)中
services.AddAutoMapper(new Type[] { typeof(DAL.MapperProfile) });            在我的数据访问项目中
namespace DAL
{
    public class MapperProfile : Profile
    {
        // place holder for AddAutoMapper (to bring in the DAL assembly)
    }
}在我的模型定义中
namespace DAL.Models
{
    public class PositionProfile : Profile
    {
        public PositionProfile()
        {
            CreateMap<Position, PositionDto_v1>();
        }
    }
    public class Position
    {
        ...
    }services.AddAutoMapper( typeof(DAL.MapperProfile) ); 而不是   services.AddAutoMapper(new Type[] { typeof(DAL.MapperProfile) });?
                    我喜欢很多答案,尤其是@saineshwar的答案。我正在将.net Core 3.0与AutoMapper 9.0一起使用,所以我觉得是时候来更新它的答案了。
对我有用的是在Startup.ConfigureServices(...)中以这种方式注册服务:
    services.AddAutoMapper(cfg => cfg.AddProfile<MappingProfile>(), 
                               AppDomain.CurrentDomain.GetAssemblies());我认为@saineshwar答案的其余部分保持完美。但是,如果有人感兴趣,我的控制器代码是:
[HttpGet("{id}")]
public async Task<ActionResult> GetIic(int id)
{
    // _context is a DB provider
    var Iic = await _context.Find(id).ConfigureAwait(false);
    if (Iic == null)
    {
        return NotFound();
    }
    var map = _mapper.Map<IicVM>(Iic);
    return Ok(map);
}和我的映射类:
public class MappingProfile : Profile
{
    public MappingProfile()
    {
        CreateMap<Iic, IicVM>()
            .ForMember(dest => dest.DepartmentName, o => o.MapFrom(src => src.Department.Name))
            .ForMember(dest => dest.PortfolioTypeName, o => o.MapFrom(src => src.PortfolioType.Name));
            //.ReverseMap();
    }
}-----编辑-----
阅读Lucian Bargaoanu评论中链接的文档后,我认为最好对此答案进行一些更改。
无参数 services.AddAutoMapper()(有@saineshwar答案)不再起作用了(至少对我而言)。但是,如果您使用NuGet程序集AutoMapper.Extensions.Microsoft.DependencyInjection,则该框架能够检查所有扩展AutoMapper.Profile的类(例如我的MappingProfile)。
因此,在我的情况下,如果该类属于同一执行程序集,则可以将服务注册缩短为services.AddAutoMapper(System.Reflection.Assembly.GetExecutingAssembly());
(一种更优雅的方法可能是使用此编码进行无参数扩展)。
谢谢,露西安!
我正在使用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
                    });
                }
            }         
        }
    }现在,在MVC Core Web Project中的Startup.cs文件中,在构造函数中,调用Mapping类,该类将在加载应用程序时初始化所有映射。
Mappings.RegisterMappings();对于ASP.NET Core(使用2.0+和3.0测试),如果您希望阅读源文档,请访问:https : //github.com/AutoMapper/AutoMapper.Extensions.Microsoft.DependencyInjection/blob/master/README.md
否则,请按照以下4个步骤操作:
从nuget安装AutoMapper.Extensions.Microsoft.DependancyInjection。
只需添加一些配置文件类。
然后将以下内容添加到您的startup.cs类中。
services.AddAutoMapper(OneOfYourProfileClassNamesHere)
然后只需将IMapper注入控制器或您需要的任何位置:
public class EmployeesController {
    private readonly IMapper _mapper;
    public EmployeesController(IMapper mapper){
        _mapper = mapper;
    }如果您现在想简单地使用ProjectTo:
var customers = await dbContext.Customers.ProjectTo<CustomerDto>(_mapper.ConfigurationProvider).ToListAsync()对于AutoMapper 9.0.0:
public static IEnumerable<Type> GetAutoMapperProfilesFromAllAssemblies()
    {
        foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
        {
            foreach (var aType in assembly.GetTypes())
            {
                if (aType.IsClass && !aType.IsAbstract && aType.IsSubclassOf(typeof(Profile)))
                    yield return aType;
            }
        }
    }MapperProfile:
public class OrganizationProfile : Profile
{
  public OrganizationProfile()
  {
    CreateMap<Foo, FooDto>();
    // Use CreateMap... Etc.. here (Profile methods are the same as configuration methods)
  }
}在您的启动中:
services.AddAutoMapper(GetAutoMapperProfilesFromAllAssemblies()
            .ToArray());在控制器或服务中:注入映射器:
private readonly IMapper _mapper;用法:
var obj = _mapper.Map<TDest>(sourceObject);services.AddAutoMapper(); 没有为我工作。(我正在使用Asp.Net Core 2.0)
如下配置后
   var config = new AutoMapper.MapperConfiguration(cfg =>
   {                 
       cfg.CreateMap<ClientCustomer, Models.Customer>();
   });初始化映射器IMapper mapper = config.CreateMapper();
并将映射器对象作为单例服务添加到服务。AddSingleton(mapper);
这样我就可以向控制器添加DI
  private IMapper autoMapper = null;
  public VerifyController(IMapper mapper)
  {              
   autoMapper = mapper;  
  }我在动作方法中使用了以下内容
  ClientCustomer customerObj = autoMapper.Map<ClientCustomer>(customer);关于theutz答案,无需在控制器构造函数中指定IMapper映射器参数。
您可以使用Mapper,因为它在代码的任何位置都是静态成员。
public class UserController : Controller {
   public someMethod()
   {
      Mapper.Map<User, UserDto>(user);
   }
}IMapper您可以模拟它,例如,如果与给定测试无关,则使其返回null。