我是.NET的新手,所以我决定使用.NET Core,而不是学习“旧方法”。我在这里找到了有关为.NET Core设置AutoMapper的详细文章,但是对于新手来说,是否有更简单的演练?
我是.NET的新手,所以我决定使用.NET Core,而不是学习“旧方法”。我在这里找到了有关为.NET Core设置AutoMapper的详细文章,但是对于新手来说,是否有更简单的演练?
Answers:
我想到了!详细信息如下:
通过NuGet将AutoMapper依赖项注入程序包添加到您的解决方案中。
为映射配置文件创建一个新类。(我在主解决方案目录中创建了一个名为的类,MappingProfile.cs
并添加了以下代码。)我将使用User
and 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.DependencyInjection
7.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。