我在ASP中使用AutoMapper。NET MVC应用程序。有人告诉我,我应该把自动取款机移走。在其他地方创建地图,因为他们有很多开销。我不太确定如何设计我的应用程序,把这些调用放在一个地方。
我有一个网络层,服务层和数据层。每个项目都有自己的特色。我用Ninject来DI所有东西。我将在web层和服务层使用AutoMapper。
那么,你为AutoMapper的CreateMap设置了什么?你把它放在哪里?你怎么称呼它?
我在ASP中使用AutoMapper。NET MVC应用程序。有人告诉我,我应该把自动取款机移走。在其他地方创建地图,因为他们有很多开销。我不太确定如何设计我的应用程序,把这些调用放在一个地方。
我有一个网络层,服务层和数据层。每个项目都有自己的特色。我用Ninject来DI所有东西。我将在web层和服务层使用AutoMapper。
那么,你为AutoMapper的CreateMap设置了什么?你把它放在哪里?你怎么称呼它?
当前回答
对于使用AutoMapper新版本(5.x)的vb.net程序员。
Global.asax.vb:
Public Class MvcApplication
Inherits System.Web.HttpApplication
Protected Sub Application_Start()
AutoMapperConfiguration.Configure()
End Sub
End Class
AutoMapperConfiguration:
Imports AutoMapper
Module AutoMapperConfiguration
Public MapperConfiguration As IMapper
Public Sub Configure()
Dim config = New MapperConfiguration(
Sub(cfg)
cfg.AddProfile(New UserProfile())
cfg.AddProfile(New PostProfile())
End Sub)
MapperConfiguration = config.CreateMapper()
End Sub
End Module
配置文件:
Public Class UserProfile
Inherits AutoMapper.Profile
Protected Overrides Sub Configure()
Me.CreateMap(Of User, UserViewModel)()
End Sub
End Class
映射:
Dim ViewUser = MapperConfiguration.Map(Of UserViewModel)(User)
其他回答
没关系,只要它是一个静态类。这都是惯例。
我们的约定是,每个“层”(web、服务、数据)都有一个名为AutoMapperXConfiguration.cs的文件,带有一个名为Configure()的方法,其中X是层。
然后Configure()方法为每个区域调用私有方法。
下面是我们web层配置的一个例子:
public static class AutoMapperWebConfiguration
{
public static void Configure()
{
ConfigureUserMapping();
ConfigurePostMapping();
}
private static void ConfigureUserMapping()
{
Mapper.CreateMap<User,UserViewModel>();
}
// ... etc
}
我们为每个“聚合”(User, Post)创建了一个方法,这样事情就被很好地分开了。
然后是Global.asax:
AutoMapperWebConfiguration.Configure();
AutoMapperServicesConfiguration.Configure();
AutoMapperDomainConfiguration.Configure();
// etc
它有点像“文字界面”——不能强制执行,但你希望它,所以你可以在必要时编码(和重构)。
编辑:
我只是想提一下我现在使用AutoMapper配置文件,所以上面的例子变成:
public static class AutoMapperWebConfiguration
{
public static void Configure()
{
Mapper.Initialize(cfg =>
{
cfg.AddProfile(new UserProfile());
cfg.AddProfile(new PostProfile());
});
}
}
public class UserProfile : Profile
{
protected override void Configure()
{
Mapper.CreateMap<User,UserViewModel>();
}
}
更干净/更坚固。
对于那些坚持以下原则的人:
使用ioc容器 我可不想因为这个破门而入 不喜欢单一的配置文件
我在配置文件和利用ioc容器之间做了一个组合:
IoC配置:
public class Automapper : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(Classes.FromThisAssembly().BasedOn<Profile>().WithServiceBase());
container.Register(Component.For<IMappingEngine>().UsingFactoryMethod(k =>
{
Profile[] profiles = k.ResolveAll<Profile>();
Mapper.Initialize(cfg =>
{
foreach (var profile in profiles)
{
cfg.AddProfile(profile);
}
});
profiles.ForEach(k.ReleaseComponent);
return Mapper.Engine;
}));
}
}
配置的例子:
public class TagStatusViewModelMappings : Profile
{
protected override void Configure()
{
Mapper.CreateMap<Service.Contracts.TagStatusViewModel, TagStatusViewModel>();
}
}
使用的例子:
public class TagStatusController : ApiController
{
private readonly IFooService _service;
private readonly IMappingEngine _mapper;
public TagStatusController(IFooService service, IMappingEngine mapper)
{
_service = service;
_mapper = mapper;
}
[Route("")]
public HttpResponseMessage Get()
{
var response = _service.GetTagStatus();
return Request.CreateResponse(HttpStatusCode.Accepted, _mapper.Map<List<ViewModels.TagStatusViewModel>>(response));
}
}
代价是必须通过IMappingEngine接口引用Mapper,而不是静态Mapper,但这是我可以接受的约定。
在新版本的AutoMapper中,使用静态方法Mapper.Map()已弃用。因此,您可以将MapperConfiguration作为静态属性添加到MvcApplication (Global.asax.cs),并使用它来创建Mapper的实例。
App_Start
public class MapperConfig
{
public static MapperConfiguration MapperConfiguration()
{
return new MapperConfiguration(_ =>
{
_.AddProfile(new FileProfile());
_.AddProfile(new ChartProfile());
});
}
}
Global.asax.cs
public class MvcApplication : System.Web.HttpApplication
{
internal static MapperConfiguration MapperConfiguration { get; private set; }
protected void Application_Start()
{
MapperConfiguration = MapperConfig.MapperConfiguration();
...
}
}
BaseController.cs
public class BaseController : Controller
{
//
// GET: /Base/
private IMapper _mapper = null;
protected IMapper Mapper
{
get
{
if (_mapper == null) _mapper = MvcApplication.MapperConfiguration.CreateMapper();
return _mapper;
}
}
}
https://github.com/AutoMapper/AutoMapper/wiki/Migrating-from-static-API
更新:这里发布的方法不再有效,因为SelfProfiler已被AutoMapper v2删除。
我会采取与Thoai类似的方法。但是我会使用内置的SelfProfiler<>类来处理映射,然后使用Mapper。SelfConfigure函数初始化。
使用该对象作为源:
public class User
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime BirthDate { get; set; }
public string GetFullName()
{
return string.Format("{0} {1}", FirstName, LastName);
}
}
这些是目的地:
public class UserViewModel
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
public class UserWithAgeViewModel
{
public int Id { get; set; }
public string FullName { get; set; }
public int Age { get; set; }
}
你可以创建这些配置文件:
public class UserViewModelProfile : SelfProfiler<User,UserViewModel>
{
protected override void DescribeConfiguration(IMappingExpression<User, UserViewModel> map)
{
//This maps by convention, so no configuration needed
}
}
public class UserWithAgeViewModelProfile : SelfProfiler<User, UserWithAgeViewModel>
{
protected override void DescribeConfiguration(IMappingExpression<User, UserWithAgeViewModel> map)
{
//This map needs a little configuration
map.ForMember(d => d.Age, o => o.MapFrom(s => DateTime.Now.Year - s.BirthDate.Year));
}
}
要在应用程序中初始化,请创建这个类
public class AutoMapperConfiguration
{
public static void Initialize()
{
Mapper.Initialize(x=>
{
x.SelfConfigure(typeof (UserViewModel).Assembly);
// add assemblies as necessary
});
}
}
将这一行添加到global.asax.cs文件中:
现在,您可以将映射类放在对您有意义的地方,而不必担心一个单一的映射类。
对于使用AutoMapper新版本(5.x)的vb.net程序员。
Global.asax.vb:
Public Class MvcApplication
Inherits System.Web.HttpApplication
Protected Sub Application_Start()
AutoMapperConfiguration.Configure()
End Sub
End Class
AutoMapperConfiguration:
Imports AutoMapper
Module AutoMapperConfiguration
Public MapperConfiguration As IMapper
Public Sub Configure()
Dim config = New MapperConfiguration(
Sub(cfg)
cfg.AddProfile(New UserProfile())
cfg.AddProfile(New PostProfile())
End Sub)
MapperConfiguration = config.CreateMapper()
End Sub
End Module
配置文件:
Public Class UserProfile
Inherits AutoMapper.Profile
Protected Overrides Sub Configure()
Me.CreateMap(Of User, UserViewModel)()
End Sub
End Class
映射:
Dim ViewUser = MapperConfiguration.Map(Of UserViewModel)(User)