在哪里放置AutoMapper.CreateMaps?[英] Where to place AutoMapper.CreateMaps?

本文是小编为大家收集整理的关于在哪里放置AutoMapper.CreateMaps?的处理/解决方法,可以参考本文帮助大家快速定位并解决问题,中文翻译不准确的可切换到English标签页查看源文。

问题描述

我在ASP.NET MVC应用程序中使用AutoMapper.有人告诉我,我应该将AutoMapper.CreateMap移动到其他地方,因为它们有很多开销.我不太确定如何设计我的应用程序将这些电话仅在1个位置.

我有一个Web层,服务层和数据层.每个项目都有自己的项目.我使用Ninject来完成所有内容.我将在网络和服务层中使用AutoMapper.

那么,您对AutoMapper的创建内容的设置是什么?你把它放在哪里?你怎么称呼它?

推荐答案

无关紧要,只要它是静态类.这全是关于 justrincy .

我们的 justrintion 是每个"层"(Web,Services,Data)都有一个称为AutoMapperXConfiguration.cs的文件,带有一种称为Configure()的方法,其中X是图层.

然后,Configure()然后调用每个区域的方法private

这是我们的Web层配置的示例:

public static class AutoMapperWebConfiguration
{
   public static void Configure()
   {
      ConfigureUserMapping();
      ConfigurePostMapping();
   }

   private static void ConfigureUserMapping()
   {
      Mapper.CreateMap<User,UserViewModel>();
   } 

   // ... etc
}

我们为每个"汇总"创建一种方法(用户,帖子),因此一切都很好地分开.

然后您的Global.asax:

AutoMapperWebConfiguration.Configure();
AutoMapperServicesConfiguration.Configure();
AutoMapperDomainConfiguration.Configure();
// etc

这有点像"单词的接口" - 无法执行它,但是您期望它,因此您可以在必要时进行编码(和重构).

编辑:

只是以为我现在提到我现在使用automapper profiles ,因此上面的示例变为:

public static class AutoMapperWebConfiguration
{
   public static void Configure()
   {
      Mapper.Initialize(cfg =>
      {
        cfg.AddProfile(new UserProfile());
        cfg.AddProfile(new PostProfile());
      });
   }
}

public class UserProfile : Profile
{
    protected override void Configure()
    {
         Mapper.CreateMap<User,UserViewModel>();
    }
}

更清洁/更健壮.

其他推荐答案

只要您的Web项目参考它所处的组件,您就可以真正将其放置在任何地方.在您的情况下,我将其放入服务层,因为Web层和服务层可以访问它稍后,如果您决定执行控制台应用程序或正在进行单元测试项目,则将从这些项目中获得映射配置.

在您的global.asax中,您将调用设置所有地图的方法.请参阅下面:

文件automapperbootstrapper.cs

public static class AutoMapperBootStrapper
{
     public static void BootStrap()
     {  
         AutoMapper.CreateMap<Object1, Object2>();
         // So on...


     }
}

global.asax在应用程序开始

只致电

AutoMapperBootStrapper.BootStrap();

现在,有些人会反对这种方法违反了一些有效论据的扎实原则.在这里,他们是为了阅读.

在bootstrapper中配置自动应用程序,以违反开放的原则?

其他推荐答案

更新:此处发布的方法没有更有效

我会采取类似的方法.但是我将使用内置的SelfProfiler<>类来处理地图,然后使用Mapper.SelfConfigure函数来初始化.

使用此对象作为源:

public class User
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public DateTime BirthDate { get; set; }
    public string GetFullName()
    {
        return string.Format("{0} {1}", FirstName, LastName);
    }
}

将这些作为目的地:

public class UserViewModel
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

public class UserWithAgeViewModel
{
    public int Id { get; set; }
    public string FullName { get; set; }
    public int Age { get; set; }
}

您可以创建这些配置文件:

public class UserViewModelProfile : SelfProfiler<User,UserViewModel>
{
    protected override void DescribeConfiguration(IMappingExpression<User, UserViewModel> map)
    {
    //This maps by convention, so no configuration needed
    }
}

public class UserWithAgeViewModelProfile : SelfProfiler<User, UserWithAgeViewModel>
{
    protected override void DescribeConfiguration(IMappingExpression<User, UserWithAgeViewModel> map)
    {
    //This map needs a little configuration
        map.ForMember(d => d.Age, o => o.MapFrom(s => DateTime.Now.Year - s.BirthDate.Year));
    }
}

要在您的应用程序中初始化,请创建此类

 public class AutoMapperConfiguration
 {
      public static void Initialize()
      {
          Mapper.Initialize(x=>
          {
              x.SelfConfigure(typeof (UserViewModel).Assembly);
              // add assemblies as necessary
          });
      }
 }

将此行添加到您的global.asax.cs文件:AutoMapperConfiguration.Initialize()

现在,您可以将映射课放在对您有意义的地方,而不必担心一个单片映射类.

本文地址:https://www.itbaoku.cn/post/627507.html

问题描述

I'm using AutoMapper in an ASP.NET MVC application. I was told that I should move the AutoMapper.CreateMap elsewhere as they have a lot of overhead. I'm not too sure how to design my application to put these calls in just 1 place.

I have a web layer, service layer and a data layer. Each a project of its own. I use Ninject to DI everything. I'll utilize AutoMapper in both web and service layers.

So what are your setup for AutoMapper's CreateMap? Where do you put it? How do you call it?

推荐答案

Doesn't matter, as long as it's a static class. It's all about convention.

Our convention is that each "layer" (web, services, data) has a single file called AutoMapperXConfiguration.cs, with a single method called Configure(), where X is the layer.

The Configure() method then calls private methods for each area.

Here's an example of our web tier config:

public static class AutoMapperWebConfiguration
{
   public static void Configure()
   {
      ConfigureUserMapping();
      ConfigurePostMapping();
   }

   private static void ConfigureUserMapping()
   {
      Mapper.CreateMap<User,UserViewModel>();
   } 

   // ... etc
}

We create a method for each "aggregate" (User, Post), so things are separated nicely.

Then your Global.asax:

AutoMapperWebConfiguration.Configure();
AutoMapperServicesConfiguration.Configure();
AutoMapperDomainConfiguration.Configure();
// etc

It's kind of like an "interface of words" - can't enforce it, but you expect it, so you can code (and refactor) if necessary.

EDIT:

Just thought I'd mention that I now use AutoMapper profiles, so the above example becomes:

public static class AutoMapperWebConfiguration
{
   public static void Configure()
   {
      Mapper.Initialize(cfg =>
      {
        cfg.AddProfile(new UserProfile());
        cfg.AddProfile(new PostProfile());
      });
   }
}

public class UserProfile : Profile
{
    protected override void Configure()
    {
         Mapper.CreateMap<User,UserViewModel>();
    }
}

Much cleaner/more robust.

其他推荐答案

You can really put it anywhere as long as your web project references the assembly that it is in. In your situation I would put it in the service layer as that will be accessible by the web layer and the service layer and later if you decide to do a console app or you are doing a unit test project the mapping configuration will be available from those projects as well.

In your Global.asax you will then call the method that sets all of your maps. See below:

File AutoMapperBootStrapper.cs

public static class AutoMapperBootStrapper
{
     public static void BootStrap()
     {  
         AutoMapper.CreateMap<Object1, Object2>();
         // So on...


     }
}

Global.asax on application start

just call

AutoMapperBootStrapper.BootStrap();

Now some people will argue against this method violates some SOLID principles, which they have valid arguments. Here they are for the reading.

Configuring Automapper in Bootstrapper violates Open-Closed Principle?

其他推荐答案

Update: The approach posted here is no more valid as SelfProfiler has been removed as of AutoMapper v2.

I would take a similar approach as Thoai. But I would use the built-in SelfProfiler<> class to handle the maps, then use the Mapper.SelfConfigure function to initialize.

Using this object as the source:

public class User
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public DateTime BirthDate { get; set; }
    public string GetFullName()
    {
        return string.Format("{0} {1}", FirstName, LastName);
    }
}

And these as the destination:

public class UserViewModel
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

public class UserWithAgeViewModel
{
    public int Id { get; set; }
    public string FullName { get; set; }
    public int Age { get; set; }
}

You can create these profiles:

public class UserViewModelProfile : SelfProfiler<User,UserViewModel>
{
    protected override void DescribeConfiguration(IMappingExpression<User, UserViewModel> map)
    {
    //This maps by convention, so no configuration needed
    }
}

public class UserWithAgeViewModelProfile : SelfProfiler<User, UserWithAgeViewModel>
{
    protected override void DescribeConfiguration(IMappingExpression<User, UserWithAgeViewModel> map)
    {
    //This map needs a little configuration
        map.ForMember(d => d.Age, o => o.MapFrom(s => DateTime.Now.Year - s.BirthDate.Year));
    }
}

To initialize in your application, create this class

 public class AutoMapperConfiguration
 {
      public static void Initialize()
      {
          Mapper.Initialize(x=>
          {
              x.SelfConfigure(typeof (UserViewModel).Assembly);
              // add assemblies as necessary
          });
      }
 }

Add this line to your global.asax.cs file: AutoMapperConfiguration.Initialize()

Now you can place your mapping classes where they make sense to you and not worry about one monolithic mapping class.