在Global.asax中多次调用AutoMapper.Configure()。
在Global.asax中多次调用AutoMapper.Configure()。
我正在使用AutoMapper来映射DTO对象和业务对象。我有两个AutoMapperConfiguration.cs文件 - 一个在我的服务层,另一个在我的Web API层。
根据以下链接中的答案所示
Where to place AutoMapper.CreateMaps?
我在我的Global.asax类中调用这两个文件的Configure()方法
AutoMapperWebConfiguration.Configure(); AutoMapperServiceConfiguration.Configure();
但是似乎我的Service Configure调用(第二个调用)覆盖了Web API层的映射(第一个调用),导致出现缺少映射的异常。
如果我反转Configure调用的顺序如下
AutoMapperServiceConfiguration.Configure(); AutoMapperWebConfiguration.Configure();
我不会为Web API映射收到异常,但是我会为Service层收到相同的映射异常。
我是否做错了什么,因为这在上面的Stack Overflow链接中明确标记为答案?
以下是我的代码:
public static class AutoMapperServiceConfiguration { public static void Configure() { Mapper.Initialize(x => { x.AddProfile(); x.AddProfile (); }); } } public class FsrsFlowTestToGenericFlowTestSimpleMappingProfile : Profile { protected override void Configure() { Mapper.CreateMap () .ConvertUsing (); } } public class FsrsFlowTestToGenericFlowTestSimpleConverter : TypeConverter { protected override GenericFlowTest ConvertCore(FsrsFlowTest source) { if (source == null) { return null; } return new GenericFlowTest { FlowTestDate = source.FlowTestDates, StaticPsi = source.HydrantStaticPsi.ToString(), ResidualPsi = source.HydrantResidualPsi.ToString(), TotalFlow = source.NffGallonsPerMinute.ToString(), FlowTestLocation = source.FsrsFlowTestLocations.Any() ? source.FsrsFlowTestLocations.First().LocationDescription : null }; } public class CmciFlowTestToGenericFlowTestSimpleMappingProfile : Profile { protected override void Configure() { Mapper.CreateMap () .ConvertUsing (); } } public class CmciFlowTestToGenericFlowTestSimpleConverter : TypeConverter { protected override GenericFlowTest ConvertCore(CmciFlowTest source) { if (source == null) { return null; } return new GenericFlowTest { FlowTestDate = source.FlowTestDates, StaticPsi = source.HydrantStaticPsi.ToString(), ResidualPsi = source.HydrantResidualPsi.ToString(), TotalFlow = source.CalculatedHydrantGallonsPerMinute.ToString(), FlowTestLocation = source.StaticLocationHydrantFlowPSI }; } } public static class AutoMapperWebConfiguration { public static void Configure() { Mapper.Initialize(x => { x.AddProfile (); x.AddProfile (); }); } } public class ServiceToWebApiMappingProfile : Profile { protected override void Configure() { Mapper.CreateMap (); } } public class WebApiToServiceMappingProfile : Profile { protected override void Configure() { Mapper.CreateMap (); } }
为了解决这个问题,我在AutoMapperWebConfiguration类中添加了service profiles,并且只在global.asax中调用AutoMapperWebConfiguration.Configure()。
在上述代码中,出现了在全局.asax文件中多次调用AutoMapper.Configure()的情况。这可能会导致以下问题:
1. AutoMapper配置被重复初始化:每次调用AutoMapper.Configure()都会初始化AutoMapper配置。在这种情况下,由于在Global.asax文件中多次调用了Configure()方法,会导致AutoMapper配置被多次初始化,可能会产生不可预料的行为。
2. 性能问题:每次调用AutoMapper.Configure()都会执行一系列配置操作,包括添加映射配置。如果在Global.asax文件中多次调用了Configure()方法,将会导致重复执行这些配置操作,从而降低性能。
为了解决上述问题,可以采取以下解决方法:
1. 只在应用程序启动时调用一次AutoMapper.Configure():在Global.asax文件中只调用一次AutoMapper.Configure()方法,以避免重复初始化AutoMapper配置。可以将该调用放在Application_Start或Application_Init事件处理程序中。
2. 将所有配置集中在一个地方:可以将所有的AutoMapper配置集中在一个地方,例如一个独立的类文件中。然后在Global.asax文件中只调用一次该配置类的Configure()方法。
下面是修改后的代码示例:
public class AutoMapperConfiguration { public static void Configure() { Mapper.Initialize(ConfigAction); } public static Action<IMapperConfigurationExpression> ConfigAction = cfg => { cfg.AddProfile<SomeProfile>(); cfg.AddProfile<SomeOtherProfileProfile>(); }; }
然后,在Global.asax文件中只调用一次AutoMapperConfiguration.Configure()方法:
protected void Application_Start() { AutoMapperConfiguration.Configure(); }
通过以上修改,可以避免多次调用AutoMapper.Configure()方法所带来的问题,并提高应用程序的性能。
在这段代码中,问题的出现是由于在Global.asax文件中使用了多个AutoMapper.Configure()方法。这个问题的解决方法是将所有的AutoMapper.Configure()方法合并成一个方法,并在Global.asax文件的Application_Start()方法中调用这个合并的方法。
具体的解决方法如下所示:
1. 首先,从现有的Mapper.Initialize()方法中提取出Action
public static ActionConfigAction = new Action (x => { x.AddProfile (); x.AddProfile (); //... more profiles });
2. 接下来,在Configure()方法中使用ConfigAction属性来代替原来的Mapper.Initialize()方法。代码如下所示:
public static void Configure() { Mapper.Initialize(ConfigAction); }
3. 最后,在Application_Start()方法中调用所有不同的ConfigAction方法。代码如下所示:
Mapper.Initialize(x => { Project1.AutoMapperConfiguration.ConfigAction.Invoke(x); Project2.AutoMapperConfiguration.ConfigAction.Invoke(x); Project3.AutoMapperConfiguration.ConfigAction.Invoke(x); //... keep adding as your project grows });
通过这种方式,将所有的AutoMapper.Configure()方法合并成一个方法,并在Application_Start()方法中调用,可以避免在不同的地方重复复制粘贴这些方法的代码,提高代码的可维护性和扩展性。
问题出现的原因是每次调用Mapper.Initialize
都会重置映射器,导致之前的所有配置都被清除。
解决方法是将AddProfile
的调用放在一个Mapper.Initialize
中,如下所示:
Mapper.Initialize(x => { x.AddProfile<CmciFlowTestToGenericFlowTestSimpleMappingProfile>(); x.AddProfile<FsrsFlowTestToGenericFlowTestSimpleMappingProfile>(); x.AddProfile<ServiceToWebApiMappingProfile>(); x.AddProfile<WebApiToServiceMappingProfile>(); });
这样做可以保证所有配置都被正确添加。
我目前正在做的就是按照上述方法,在AutoMapperWebConfiguration
类中从我的服务层添加配置文件。我之前被这篇文章所困惑:stackoverflow.com/questions/6825244/…,因为其中显示在全局文件global.asax
中进行了多次Configure()
的调用。