在Global.asax中多次调用AutoMapper.Configure()。

9 浏览
0 Comments

在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()。

0
0 Comments

在上述代码中,出现了在全局.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()方法所带来的问题,并提高应用程序的性能。

0
0 Comments

在这段代码中,问题的出现是由于在Global.asax文件中使用了多个AutoMapper.Configure()方法。这个问题的解决方法是将所有的AutoMapper.Configure()方法合并成一个方法,并在Global.asax文件的Application_Start()方法中调用这个合并的方法。

具体的解决方法如下所示:

1. 首先,从现有的Mapper.Initialize()方法中提取出Action部分,并将其放入一个公共属性中。在代码中,这个属性被称为ConfigAction。代码如下所示:

public static Action ConfigAction = 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()方法中调用,可以避免在不同的地方重复复制粘贴这些方法的代码,提高代码的可维护性和扩展性。

0
0 Comments

问题出现的原因是每次调用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()的调用。

0