集成和配置AutoMapper

 

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

你可能感兴趣的:(mapper)