AutoMapper的基本使用请参考 : http://www.cnblogs.com/ljzforever/archive/2011/12/29/2305500.html
学习一下Nop是如何配置和集成AutoMapper的。
IStartupTask.cs
namespace
Nop.Core.Infrastructure
{
public
interface
IStartupTask
{
void
Execute();
int
Order {
get
; }
}
}
之前的随便介绍了 ITypeFinder实现 , 项目启动时,ITypeFinder会找到项目中所有继承 IStartupTask 接口的实现。其中就有AutoMapperStartupTask
using
AutoMapper;
using
Nop.Admin.Models.Blogs;
using
Nop.Admin.Models.Catalog;
using
Nop.Admin.Models.Cms;
using
Nop.Admin.Models.Common;
using
Nop.Admin.Models.Customers;
using
Nop.Admin.Models.Directory;
using
Nop.Admin.Models.Discounts;
using
Nop.Admin.Models.ExternalAuthentication;
using
Nop.Admin.Models.Forums;
using
Nop.Admin.Models.Localization;
using
Nop.Admin.Models.Logging;
using
Nop.Admin.Models.Messages;
using
Nop.Admin.Models.News;
using
Nop.Admin.Models.Orders;
using
Nop.Admin.Models.Payments;
using
Nop.Admin.Models.Plugins;
using
Nop.Admin.Models.Polls;
using
Nop.Admin.Models.Settings;
using
Nop.Admin.Models.Shipping;
using
Nop.Admin.Models.Tax;
using
Nop.Admin.Models.Topics;
using
Nop.Core.Domain.Blogs;
using
Nop.Core.Domain.Catalog;
using
Nop.Core.Domain.Common;
using
Nop.Core.Domain.Customers;
using
Nop.Core.Domain.Directory;
using
Nop.Core.Domain.Discounts;
using
Nop.Core.Domain.Forums;
using
Nop.Core.Domain.Localization;
using
Nop.Core.Domain.Logging;
using
Nop.Core.Domain.Media;
using
Nop.Core.Domain.Messages;
using
Nop.Core.Domain.News;
using
Nop.Core.Domain.Orders;
using
Nop.Core.Domain.Polls;
using
Nop.Core.Domain.Shipping;
using
Nop.Core.Domain.Tax;
using
Nop.Core.Domain.Topics;
using
Nop.Core.Infrastructure;
using
Nop.Core.Plugins;
using
Nop.Services.Authentication.External;
using
Nop.Services.Cms;
using
Nop.Services.Messages;
using
Nop.Services.Payments;
using
Nop.Services.Shipping;
using
Nop.Services.Tax;
namespace
Nop.Admin.Infrastructure
{
public
class
AutoMapperStartupTask : IStartupTask
{
public
void
Execute()
{
//
TODO remove 'CreatedOnUtc' ignore mappings because now presentation layer models have 'CreatedOn' property and core entities have 'CreatedOnUtc' property (distinct names)
//
address
Mapper.CreateMap<Address, AddressModel>
()
.ForMember(dest
=> dest.AddressHtml, mo =>
mo.Ignore())
.ForMember(dest
=> dest.AvailableCountries, mo =>
mo.Ignore())
.ForMember(dest
=> dest.AvailableStates, mo =>
mo.Ignore())
.ForMember(dest
=> dest.FirstNameDisabled, mo =>
mo.Ignore())
.ForMember(dest
=> dest.LastNameDisabled, mo =>
mo.Ignore())
.ForMember(dest
=> dest.EmailDisabled, mo =>
mo.Ignore())
.ForMember(dest
=> dest.CompanyDisabled, mo =>
mo.Ignore())
.ForMember(dest
=> dest.CountryDisabled, mo =>
mo.Ignore())
.ForMember(dest
=> dest.StateProvinceDisabled, mo =>
mo.Ignore())
.ForMember(dest
=> dest.CityDisabled, mo =>
mo.Ignore())
.ForMember(dest
=> dest.Address1Disabled, mo =>
mo.Ignore())
.ForMember(dest
=> dest.Address2Disabled, mo =>
mo.Ignore())
.ForMember(dest
=> dest.ZipPostalCodeDisabled, mo =>
mo.Ignore())
.ForMember(dest
=> dest.PhoneNumberDisabled, mo =>
mo.Ignore())
.ForMember(dest
=> dest.FaxNumberDisabled, mo =>
mo.Ignore());
Mapper.CreateMap
<AddressModel, Address>
()
.ForMember(dest
=> dest.CreatedOnUtc, mo =>
mo.Ignore())
.ForMember(dest
=> dest.Country, mo =>
mo.Ignore())
.ForMember(dest
=> dest.StateProvince, mo =>
mo.Ignore());
……
}
然后是单元测试,AutoMapperStartupTask 提交后进行集成测试,验证配置是否正确。
[TestFixture]
public
class
AutoMapperConfigurationTest
{
[Test]
public
void
Configuration_is_valid()
{
var
autoMapperStartupTask =
new
AutoMapperStartupTask();
autoMapperStartupTask.Execute();
Mapper.AssertConfigurationIsValid();
}
}
这里一个专门用于Mapper的扩展方法。
public
static
class
MappingExtensions
{
#region
Category
public
static
CategoryModel ToModel(
this
Category entity)
{
return
Mapper.Map<Category, CategoryModel>
(entity);
}
public
static
Category ToEntity(
this
CategoryModel model)
{
return
Mapper.Map<CategoryModel, Category>
(model);
}
public
static
Category ToEntity(
this
CategoryModel model, Category destination)
{
return
Mapper.Map(model, destination);
}
。。。
最后是调用完成ViewModel,Entity的转换
var
gridModel =
new
GridModel<CategoryModel>
{
Data
= categories.Select(x =>
{
var
categoryModel =
x.ToModel();
categoryModel.Breadcrumb
=
x.GetCategoryBreadCrumb(_categoryService);
return
categoryModel;
}),
Total
=
categories.TotalCount
};
return
new
JsonResult
{
Data
=
gridModel
};
总结: 光学会如何使用一个工具还不行,还要学习它如何能和自己的项目进行良好的集成。。使用不当的话反而影响插件和项目的扩展性,增加项目的复杂度。Nop的模块划分很清晰,方便了今后学习和改造。
参考:
http://www.cnblogs.com/ljzforever/archive/2011/12/29/2305500.html

