我有一個3層架構Web Api解決方案,里面有3個項目:數(shù)據(jù),業(yè)務和表示層.我需要在兩個業(yè)務和表示層中初始化兩個不同的映射器.
我已經創(chuàng)建了一個靜態(tài)類和方法來初始化業(yè)務邏輯中的一個映射器:
using AutoMapper;using Shop.BLL.DTOModels;using Shop.DAL.Models;using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace Shop.BLL.InitMapper{ public static class InitializeMapperBLL { public static void RegisterMappings() { Mapper.Initialize(cfg => cfg.CreateMap<Category, DTOCategoryModel>()); } }}
并稱之為:
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using Shop.DAL.Repositories;using AutoMapper;using Shop.BLL.DTOModels;using Shop.DAL.Models;using Shop.BLL.Interfaces;using Shop.DAL.Interfaces;using Shop.BLL.InitMapper;namespace Shop.BLL.Services{ public class CategoryService : ICategoryService { IUnitOfWork Database { get; set; } public CategoryService(IUnitOfWork uow) { Database = uow; } public IEnumerable<DTOCategoryModel> GetCategories() {//I call it here InitializeMapperBLL.RegisterMappings(); return Mapper.Map<IEnumerable<Category>, List<DTOCategoryModel>>(Database.Categories.GetAll()); } public void Dispose() { Database.Dispose(); } }}
在表示層我做同樣的事情:
using AutoMapper;using Shop.API.ViewModels;using Shop.BLL.DTOModels;using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace Shop.API.MapperInit{ public static class InitializeMapperAPI { public static void RegisterMappings() { Mapper.Initialize(cfg => cfg.CreateMap<DTOCategoryModel, CategoryViewModel>()); } }}
并調用Global.asax
protected void Application_Start() { AreaRegistration.RegisterAllAreas(); GlobalConfiguration.Configure(WebApiConfig.Register); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); //here I call it InitializeMapperAPI.RegisterMappings(); CreateKernel(); }
我已經初始化了錯誤Mapper.您必須為每個應用程序域/進程調用一次Initialize.
如何解決這個問題呢?
解決方法:
您可以使用反射和自動播放器配置文件的一種方法.這在我用過的項目中非常有效.
在每個項目/圖層中創(chuàng)建一個automapper配置文件類.每個配置文件類應僅包含它自己需要的映射.以下是其中一個的示例:
//Profile here is of type AutoMapper.Profile public class BusinessLayerMapperConfig : Profile { public BusinessLayerMapperConfig() { //create layer specific maps CreateMap<MyObjectDTO, MyObjectViewModel>(); } public override string ProfileName { get { return this.GetType().ToString(); } } }
然后真正靠近應用程序入口點的地方(我從Global.asax.cs中的ApplicationStart方法調用以下方法),初始化所有的配置文件,如下所示:
public static void RegisterMaps() { //get all projects' AutoMapper profiles using reflection var assembliesToScan = System.AppDomain.CurrentDomain.GetAssemblies(); var allTypes = assembliesToScan.SelectMany(a => a.ExportedTypes).ToArray(); var profiles = allTypes .Where(t => typeof(Profile).GetTypeInfo().IsAssignableFrom(t.GetTypeInfo())) .Where(t => !t.GetTypeInfo().IsAbstract); //add each profile to our static AutoMapper Mapper.Initialize(cfg => { foreach (var profile in profiles) { cfg.AddProfile(profile); } }); }
這將允許您按照它們使用的圖層邏輯分隔您的地圖,并確保您只初始化它們一次.
來源:https://www.icode9.com/content-1-315301.html