Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/wix/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在类库项目中配置自动映射器?_C#_Automapper_Automapper 2_Automapper 3 - Fatal编程技术网

C# 如何在类库项目中配置自动映射器?

C# 如何在类库项目中配置自动映射器?,c#,automapper,automapper-2,automapper-3,C#,Automapper,Automapper 2,Automapper 3,我第一次使用自动映射 我正在开发c#应用程序,我想使用自动映射器 (我只是想知道如何使用它,所以我没有asp.net应用程序,也没有MVC应用程序。) 我有三个类库项目 我想在服务项目中编写传输流程 因此,我想知道如何以及在哪里配置自动映射器 您可以将配置放置在任何位置: public class AutoMapperConfiguration { public static void Configure() { Mapper.Initialize(x =>

我第一次使用自动映射

我正在开发c#应用程序,我想使用自动映射器

(我只是想知道如何使用它,所以我没有asp.net应用程序,也没有MVC应用程序。)

我有三个类库项目

我想在服务项目中编写传输流程


因此,我想知道如何以及在哪里配置自动映射器

您可以将配置放置在任何位置:

public class AutoMapperConfiguration
{
    public static void Configure()
    {
        Mapper.Initialize(x =>
            {
                x.AddProfile<MyMappings>();              
            });
    }
}

 public class MyMappings : Profile
{
    public override string ProfileName
    {
        get { return "MyMappings"; }
    }

    protected override void Configure()
    {
    ......
    }
库之外的任何人都不必配置AutoMapper 我建议您使用。这样,库外的任何人都不必调用任何配置方法。您可以在类库中定义
MapperConfiguration
并从中创建映射器

var config = new MapperConfiguration(cfg => {
    cfg.AddProfile<AppProfile>();
    cfg.CreateMap<Source, Dest>();
});

IMapper mapper = config.CreateMapper();
// or
IMapper mapper = new Mapper(config);
var dest = mapper.Map<Source, Dest>(new Source());
var config=new-MapperConfiguration(cfg=>{
AddProfile();
CreateMap();
});
IMapper mapper=config.CreateMapper();
//或
IMapper映射器=新映射器(配置);
var dest=mapper.Map(新的Source());

因此,根据Bruno的回答,我提出了以下解决方案,让它只运行一次,并在类库中完全隔离,这与公认的答案不同,后者依赖库的使用者在父项目中配置映射:

public static class Mapping
{
    private static readonly Lazy<IMapper> Lazy = new Lazy<IMapper>(() =>
    {
        var config = new MapperConfiguration(cfg => {
            // This line ensures that internal properties are also mapped over.
            cfg.ShouldMapProperty = p => p.GetMethod.IsPublic || p.GetMethod.IsAssembly;
            cfg.AddProfile<MappingProfile>();
        });
        var mapper = config.CreateMapper();
        return mapper;
    });

    public static IMapper Mapper => Lazy.Value;
}

public class MappingProfile : Profile
{
    public MappingProfile()
    {
        CreateMap<Source, Destination>();
        // Additional mappings here...
    }
}
公共静态类映射
{
私有静态只读惰性=新惰性(()=>
{
var config=new-MapperConfiguration(cfg=>{
//此行可确保内部属性也映射到上。
cfg.ShouldMapProperty=p=>p.GetMethod.IsPublic | | p.GetMethod.IsAssembly;
AddProfile();
});
var mapper=config.CreateMapper();
返回映射器;
});
公共静态IMapper=>Lazy.Value;
}
公共类映射配置文件:配置文件
{
公共映射配置文件()
{
CreateMap();
//这里有其他映射。。。
}
}
然后在需要将一个对象映射到另一个对象的代码中,只需执行以下操作:

var destination = Mapping.Mapper.Map<Destination>(yourSourceInstance);
var destination=Mapping.Mapper.Map(yourSourceInstance);

注意:此代码基于AutoMapper 6.2,可能需要对旧版本的AutoMapper进行一些调整。

Marko的答案是正确的

我们也可以使用下面一个简单的解决方案

 public static class ObjectMapper
{
    public static IMapper Mapper
    {
        get
        {
            return AutoMapper.Mapper.Instance;
        }
    }
    static ObjectMapper()
    {
        CreateMap();
    }
    private static void CreateMap()
    {
        AutoMapper.Mapper.Initialize(cfg =>
        {
            cfg.CreateMap<SourceClass, DestinationClass>();
        });
    }
}
公共静态类ObjectMapper
{
公共静态IMapper映射器
{
得到
{
返回AutoMapper.Mapper.Instance;
}
}
静态对象映射器()
{
CreateMap();
}
私有静态void CreateMap()
{
AutoMapper.Mapper.Initialize(cfg=>
{
CreateMap();
});
}
}
我们可以像这样使用它。
public class SourceClass
{
    public string Name { get; set; }
}
public class DestinationClass
{
    public string Name { get; set; }
}
SourceClass c1 = new SourceClass() { Name = "Mr.Ram" };

DestinationClass c2 = ObjectMapper.Mapper.Map<DestinationClass>(c1);
公共类SourceClass
{
公共字符串名称{get;set;}
}
公共类DestinationClass
{
公共字符串名称{get;set;}
}
SourceClass c1=新的SourceClass(){Name=“Mr.Ram”};
DestinationClass c2=ObjectMapper.Mapper.Map(c1);

我使用了Patel Vishal的解决方案,并根据自己的需要进行了定制。 它是一个泛型类,确保每个对象映射在内存中只保存一个映射实例

  • TModel-是一个DTO对象
  • TData-是实体框架中的数据库表对象
  • IBaseModel-是DTO对象的基类,它有一个属性:ID
  • IBaseModel-是仅具有ID属性的实体框架数据库实体的基类

  • 公共静态类ObjectMapper
    其中TModel:class,DTO.IBaseModel,new()
    其中TData:class,IBaseModel,new()
    {
    私有静态只读MapperConfiguration\u MapperConfiguration;
    公共静态IMapper映射器=>新映射器(\u mapperConfiguration);
    静态对象映射器()
    {
    _mapperConfiguration???=CreateMap();
    }
    私有静态MapperConfiguration CreateMap()
    {
    返回新的(cfg=>
    {
    CreateMap();
    });
    }
    }
    

    我在BaseService(服务/存储库模式)中使用此类,如下所示:

    公共虚拟TModel转换(TData t)
    {
    返回ObjectMapper.Mapper.Map(t);
    }
    

    如您所见,这是一种虚拟方法。如果继承服务需要自定义,则可以覆盖映射。

    谢谢。这是最好的答案,因为它不依赖于任何东西,只依赖于自身。这是一个自包含的解决方案,可用于任何类型的应用程序,而不仅仅是类库。谢谢,@Marko。我们可以把这段代码放在类库的什么地方,以便自动调用它(只调用一次)?@kamalpreet在类的静态构造函数中。或者看看它在asp.net内核中是否也能工作?
    public class SourceClass
    {
        public string Name { get; set; }
    }
    public class DestinationClass
    {
        public string Name { get; set; }
    }
    SourceClass c1 = new SourceClass() { Name = "Mr.Ram" };
    
    DestinationClass c2 = ObjectMapper.Mapper.Map<DestinationClass>(c1);
    
    public static class ObjectMapper<TModel, TData>
        where TModel : class, DTO.IBaseModel, new() 
        where TData : class, IBaseModel, new()
    {
        private static readonly MapperConfiguration _mapperConfiguration;
        public static IMapper Mapper => new Mapper(_mapperConfiguration);
    
        static ObjectMapper()
        {
            _mapperConfiguration ??= CreateMap();
        }
    
        private static MapperConfiguration CreateMap()
        {
            return new (cfg =>
            {
                cfg.CreateMap<TData, TModel>();
            });
        }
    }
    
        public virtual TModel Convert(TData t)
        {
            return ObjectMapper<TModel, TData>.Mapper.Map<TModel>(t);
        }