本章主要简单介绍下在ASP.NET Core中如何使用AutoMapper进行实体映射。在正式进入主题之前我们来看下几个概念:

1、数据库持久化对象PO(Persistent Object):顾名思义,这个对象是用来将我们的数据持久化到数据库,一般来说,持久化对象中的字段会与数据库中对应的 table 保持一致。

2、视图对象VO(View Object):视图对象 VO 是面向前端用户页面的,一般会包含呈现给用户的某个页面/组件中所包含的所有数据字段信息。

3、数据传输对象DTO(Data Transfer Object):数据传输对象 DTO 一般用于前端展示层与后台服务层之间的数据传递,以一种媒介的形式完成 数据库持久化对象 与 视图对象 之间的数据传递。

4、AutoMapper 是一个 OOM(Object-Object-Mapping) 组件,从名字上就可以看出来,这一系列的组件主要是为了帮助我们实现实体间的相互转换,从而避免我们每次都采用手工编写代码的方式进行转换。

接下来正式进入本章主题,我们直接通过一个使用案例来说明在ASP.NET Core中如何使用AutoMapper进行实体映射。

在之前的基础上我们再添加一个web项目TianYa.DotNetShare.AutoMapperDemo用于演示AutoMapper的使用,首先来看一下我们的解决方案:

分别对上面的工程进行简单的说明:

1、TianYa.DotNetShare.Model:为demo的实体层

2、TianYa.DotNetShare.Repository:为demo的仓储层即数据访问层

3、TianYa.DotNetShare.Service:为demo的服务层即业务逻辑层

4、TianYa.DotNetShare.SharpCore:为demo的Sharp核心类库

5、TianYa.DotNetShare.AutoMapperDemo:为demo的web层项目,MVC框架

约定:

1、公共的类库,我们选择.NET Standard 2.0作为目标框架,可与Framework进行共享。

2、本demo的web项目为ASP.NET Core Web 应用程序(.NET Core 2.2) MVC框架。

除了上面提到的这些,别的在之前的文章中就已经详细的介绍过了,本demo没有用到就不做过多的阐述了。

一、实体层

为了演示接下来我们创建一些实体,如下图所示:

1、学生类Student(数据库持久化对象)(PO)

using System;
using System.Collections.Generic;
using System.Text; namespace TianYa.DotNetShare.Model
{
/// <summary>
/// 学生类
/// </summary>
public class Student
{
/// <summary>
/// 唯一ID
/// </summary>
public string UUID { get; set; } = Guid.NewGuid().ToString().Replace("-", ""); /// <summary>
/// 学号
/// </summary>
public string StuNo { get; set; } /// <summary>
/// 姓名
/// </summary>
public string Name { get; set; } /// <summary>
/// 年龄
/// </summary>
public int Age { get; set; } /// <summary>
/// 性别
/// </summary>
public string Sex { get; set; } /// <summary>
/// 出生日期
/// </summary>
public DateTime Birthday { get; set; } /// <summary>
/// 年级编号
/// </summary>
public short GradeId { get; set; } /// <summary>
/// 是否草稿
/// </summary>
public bool IsDraft { get; set; } = false; /// <summary>
/// 学生发布的成果
/// </summary>
public virtual IList<TecModel> Tecs { get; set; }
}
}

2、学生视图类V_Student(视图对象)(VO)

using System;
using System.Collections.Generic;
using System.Text; namespace TianYa.DotNetShare.Model.ViewModel
{
/// <summary>
/// 学生视图对象
/// </summary>
public class V_Student
{
/// <summary>
/// 唯一ID
/// </summary>
public string UUID { get; set; } /// <summary>
/// 学号
/// </summary>
public string StuNo { get; set; } /// <summary>
/// 姓名
/// </summary>
public string Name { get; set; } /// <summary>
/// 年龄
/// </summary>
public int Age { get; set; } /// <summary>
/// 性别
/// </summary>
public string Sex { get; set; } /// <summary>
/// 出生日期
/// </summary>
public string Birthday { get; set; } /// <summary>
/// 年级编号
/// </summary>
public short GradeId { get; set; } /// <summary>
/// 年级名称
/// </summary>
public string GradeName => GradeId == ? "大一" : "未知"; /// <summary>
/// 发布的成果数量
/// </summary>
public short TecCounts { get; set; } /// <summary>
/// 操作
/// </summary>
public string Operate { get; set; }
}
}

3、用于配合演示的成果实体

using System;
using System.Collections.Generic;
using System.Text; namespace TianYa.DotNetShare.Model
{
/// <summary>
/// 成果
/// </summary>
public class TecModel
{
/// <summary>
/// 唯一ID
/// </summary>
public string UUID { get; set; } = Guid.NewGuid().ToString().Replace("-", ""); /// <summary>
/// 成果名称
/// </summary>
public string TecName { get; set; }
}
}

二、服务层

本demo的服务层需要引用以下几个程序集:

1、我们的实体层TianYa.DotNetShare.Model

2、我们的仓储层TianYa.DotNetShare.Repository

3、需要从NuGet上添加AutoMapper

约定:

1、服务层接口都以“I”开头,以“Service”结尾。服务层实现都以“Service”结尾。

为了演示,我们新建一个Student的服务层接口IStudentService.cs

using System;
using System.Collections.Generic;
using System.Text; using TianYa.DotNetShare.Model;
using TianYa.DotNetShare.Model.ViewModel; namespace TianYa.DotNetShare.Service
{
/// <summary>
/// 学生类服务层接口
/// </summary>
public interface IStudentService
{
/// <summary>
/// 根据学号获取学生信息
/// </summary>
/// <param name="stuNo">学号</param>
/// <returns>学生信息</returns>
Student GetStuInfo(string stuNo); /// <summary>
/// 获取学生视图对象
/// </summary>
/// <param name="stu">学生数据库持久化对象</param>
/// <returns>学生视图对象</returns>
V_Student GetVStuInfo(Student stu);
}
}

接着我们同样在Impl中新建一个Student的服务层实现StudentService.cs,该类实现了IStudentService接口

using System;
using System.Collections.Generic;
using System.Text; using TianYa.DotNetShare.Model;
using TianYa.DotNetShare.Model.ViewModel;
using TianYa.DotNetShare.Repository;
using AutoMapper; namespace TianYa.DotNetShare.Service.Impl
{
/// <summary>
/// 学生类服务层
/// </summary>
public class StudentService : IStudentService
{
/// <summary>
/// 定义仓储层学生抽象类对象
/// </summary>
protected IStudentRepository StuRepository; /// <summary>
/// 实体自动映射
/// </summary>
protected readonly IMapper _mapper; /// <summary>
/// 空构造函数
/// </summary>
public StudentService() { } /// <summary>
/// 构造函数
/// </summary>
/// <param name="stuRepository">仓储层学生抽象类对象</param>
/// <param name="mapper">实体自动映射</param>
public StudentService(IStudentRepository stuRepository, IMapper mapper)
{
this.StuRepository = stuRepository;
_mapper = mapper;
} /// <summary>
/// 根据学号获取学生信息
/// </summary>
/// <param name="stuNo">学号</param>
/// <returns>学生信息</returns>
public Student GetStuInfo(string stuNo)
{
var stu = StuRepository.GetStuInfo(stuNo);
return stu;
} /// <summary>
/// 获取学生视图对象
/// </summary>
/// <param name="stu">学生数据库持久化对象</param>
/// <returns>学生视图对象</returns>
public V_Student GetVStuInfo(Student stu)
{
return _mapper.Map<Student, V_Student>(stu);
}
}
}

最后添加一个实体映射配置类MyProfile,该类继承于AutoMapper的Profile类,在配置类MyProfile的无参构造函数中通过泛型的 CreateMap 方法写映射规则。

using System;
using System.Collections.Generic;
using TianYa.DotNetShare.Model;
using TianYa.DotNetShare.Model.ViewModel; namespace TianYa.DotNetShare.Service.AutoMapperConfig
{
/// <summary>
/// 实体映射配置类
/// </summary>
public class MyProfile : AutoMapper.Profile
{
/// <summary>
/// 构造函数
/// </summary>
public MyProfile()
{
// 配置 mapping 规则 CreateMap<Student, V_Student>();
}
}
}

服务层就这样了,接下来就是重头戏了,如果有多个实体映射配置类,那么要如何实现一次性依赖注入呢,这个我们在Sharp核心类库中去统一处理。

三、Sharp核心类库

在之前项目的基础上,我们还需要从NuGet上引用以下2个程序集用于实现实体自动映射:

//AutoMapper基础组件
AutoMapper
//AutoMapper依赖注入辅助组件
AutoMapper.Extensions.Microsoft.DependencyInjection

1、首先我们添加一个反射帮助类ReflectionHelper

using System;
using System.Collections.Generic;
using System.Reflection;
using System.Linq;
using System.Runtime.Loader;
using Microsoft.Extensions.DependencyModel; namespace TianYa.DotNetShare.SharpCore
{
/// <summary>
/// 反射帮助类
/// </summary>
public static class ReflectionHelper
{
/// <summary>
/// 获取类以及类实现的接口键值对
/// </summary>
/// <param name="assemblyName">程序集名称</param>
/// <returns>类以及类实现的接口键值对</returns>
public static Dictionary<Type, List<Type>> GetClassInterfacePairs(this string assemblyName)
{
//存储 实现类 以及 对应接口
Dictionary<Type, List<Type>> dic = new Dictionary<Type, List<Type>>();
Assembly assembly = GetAssembly(assemblyName);
if (assembly != null)
{
Type[] types = assembly.GetTypes();
foreach (var item in types.AsEnumerable().Where(x => !x.IsAbstract && !x.IsInterface && !x.IsGenericType))
{
dic.Add(item, item.GetInterfaces().Where(x => !x.IsGenericType).ToList());
}
} return dic;
} /// <summary>
/// 获取指定的程序集
/// </summary>
/// <param name="assemblyName">程序集名称</param>
/// <returns>程序集</returns>
public static Assembly GetAssembly(this string assemblyName)
{
return GetAllAssemblies().FirstOrDefault(assembly => assembly.FullName.Contains(assemblyName));
} /// <summary>
/// 获取所有的程序集
/// </summary>
/// <returns>程序集集合</returns>
private static List<Assembly> GetAllAssemblies()
{
var list = new List<Assembly>();
var deps = DependencyContext.Default;
var libs = deps.CompileLibraries.Where(lib => !lib.Serviceable && lib.Type != "package");//排除所有的系统程序集、Nuget下载包
foreach (var lib in libs)
{
try
{
var assembly = AssemblyLoadContext.Default.LoadFromAssemblyName(new AssemblyName(lib.Name));
list.Add(assembly);
}
catch (Exception)
{
// ignored
}
} return list;
}
}
}

2、接着我们添加一个AutoMapper扩展类

using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq; using AutoMapper; namespace TianYa.DotNetShare.SharpCore.Extensions
{
/// <summary>
/// AutoMapper扩展类
/// </summary>
public static class AutoMapperExtensions
{
/// <summary>
/// 通过反射批量注入AutoMapper映射规则
/// </summary>
/// <param name="services">服务</param>
/// <param name="assemblyNames">程序集数组 如:["TianYa.DotNetShare.Repository","TianYa.DotNetShare.Service"],无需写dll</param>
public static void RegisterAutoMapperProfiles(this IServiceCollection services, params string[] assemblyNames)
{
foreach (string assemblyName in assemblyNames)
{
var listProfile = new List<Type>();
var parentType = typeof(Profile);
//所有继承于Profile的类
var types = assemblyName.GetAssembly().GetTypes()
.Where(item => item.BaseType != null && item.BaseType.Name == parentType.Name); if (types != null && types.Count() > )
{
listProfile.AddRange(types);
} if (listProfile.Count() > )
{
//映射规则注入
services.AddAutoMapper(listProfile.ToArray());
}
}
} /// <summary>
/// 通过反射批量注入AutoMapper映射规则
/// </summary>
/// <param name="services">服务</param>
/// <param name="profileTypes">Profile的子类</param>
public static void RegisterAutoMapperProfiles(this IServiceCollection services, params Type[] profileTypes)
{
var listProfile = new List<Type>();
var parentType = typeof(Profile); foreach (var item in profileTypes)
{
if (item.BaseType != null && item.BaseType.Name == parentType.Name)
{
listProfile.Add(item);
}
} if (listProfile.Count() > )
{
//映射规则注入
services.AddAutoMapper(listProfile.ToArray());
}
}
}
}

不难看出,该类实现AutoMapper一次性注入的核心思想是:通过反射获取程序集中继承了AutoMapper.Profile类的所有子类,然后利用AutoMapper依赖注入辅助组件进行批量依赖注入。

四、Web层

本demo的web项目需要引用以下几个程序集:

1、TianYa.DotNetShare.Model 我们的实体层

2、TianYa.DotNetShare.Service 我们的服务层

3、TianYa.DotNetShare.SharpCore 我们的Sharp核心类库

到了这里我们所有的工作都已经准备好了,接下来就是开始做注入工作了。

打开我们的Startup.cs文件进行注入工作:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using TianYa.DotNetShare.SharpCore.Extensions;
using TianYa.DotNetShare.Service.AutoMapperConfig; namespace TianYa.DotNetShare.AutoMapperDemo
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
} public IConfiguration Configuration { get; } // This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
}); services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2); //DI依赖注入,批量注入指定的程序集
services.RegisterTianYaSharpService(new string[] { "TianYa.DotNetShare.Repository", "TianYa.DotNetShare.Service" });
//注入AutoMapper映射规则
//services.RegisterAutoMapperProfiles(typeof(MyProfile)); //如果MyProfile写在Web项目中可通过该方式注入AutoMapper映射规则
services.RegisterAutoMapperProfiles(new string[] { "TianYa.DotNetShare.Service" });
} // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
} app.UseStaticFiles();
app.UseCookiePolicy(); app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
}
}

其中用来实现批量依赖注入的只要简单的几句话就搞定了,如下所示:

//DI依赖注入,批量注入指定的程序集
services.RegisterTianYaSharpService(new string[] { "TianYa.DotNetShare.Repository", "TianYa.DotNetShare.Service" });
//注入AutoMapper映射规则
//services.RegisterAutoMapperProfiles(typeof(MyProfile)); //如果MyProfile写在Web项目中可通过该方式注入AutoMapper映射规则
services.RegisterAutoMapperProfiles(new string[] { "TianYa.DotNetShare.Service" });

Sharp核心类库在底层实现了批量注入的逻辑,程序集的注入必须按照先后顺序进行,先进行仓储层注入然后再进行服务层注入。

接下来我们来看看控制器里面怎么弄:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using AutoMapper; using TianYa.DotNetShare.AutoMapperDemo.Models;
using TianYa.DotNetShare.Model;
using TianYa.DotNetShare.Model.ViewModel;
using TianYa.DotNetShare.Service; namespace TianYa.DotNetShare.AutoMapperDemo.Controllers
{
public class HomeController : Controller
{
/// <summary>
/// 自动映射
/// </summary>
private readonly IMapper _mapper; /// <summary>
/// 定义服务层学生抽象类对象
/// </summary>
protected IStudentService StuService; /// <summary>
/// 构造函数注入
/// </summary>
public HomeController(IMapper mapper, IStudentService stuService)
{
_mapper = mapper;
StuService = stuService;
} public IActionResult Index()
{
var model = new Student
{
StuNo = "",
Name = "张三",
Age = ,
Sex = "男",
Birthday = DateTime.Now.AddYears(-),
GradeId = ,
Tecs = new List<TecModel>
{
new TecModel
{
TecName = "成果名称"
}
}
}; var v_model = _mapper.Map<Student, V_Student>(model);
var v_model_s = StuService.GetVStuInfo(model); return View();
} public IActionResult Privacy()
{
return View();
} [ResponseCache(Duration = , Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error()
{
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}
}
}

到这里我们基础的自动实体映射就算是处理好了,最后我们调试起来看下结果:

小结:

1、在该例子中我们实现了从Student(PO) 到 V_Student(VO)的实体映射。

2、可以发现在服务层中也注入成功了,说明AutoMapper依赖注入辅助组件的注入是全局的。

3、AutoMapper 默认是通过匹配字段名称和类型进行自动匹配,所以如果你进行转换的两个类中的某些字段名称不一样,这时我们就需要进行手动的编写转换规则。

4、在AutoMapper中,我们可以通过 ForMember 方法对映射规则做进一步的加工。

5、当我们将所有的实体映射规则注入到 IServiceCollection 中后,就可以在代码中使用这些实体映射规则。和其它通过依赖注入的接口使用方式相同,我们只需要在使用到的地方注入 IMapper 接口,然后通过 Map 方法就可以完成实体间的映射。

接下来我们针对小结的第4点举些例子来说明一下:

1、在映射时忽略某些不需要的字段,不对其进行映射。

修改映射规则如下:

/// <summary>
/// 实体映射配置类
/// </summary>
public class MyProfile : AutoMapper.Profile
{
/// <summary>
/// 构造函数
/// </summary>
public MyProfile()
{
// 配置 mapping 规则
//<源对象,目标对象> 实现从 源对象 到 目标对象 的实体映射
CreateMap<Student, V_Student>()
.ForMember(destination => destination.UUID, opt => opt.Ignore()); //不对UUID进行映射
}
}

来看下调试结果:

此时可以发现映射得到的对象v_model_s中的UUID为null了。

2、可以指明V_Student中的属性TecCounts值是来自Student中的Tecs的集合元素个数。

修改映射规则如下:

/// <summary>
/// 实体映射配置类
/// </summary>
public class MyProfile : AutoMapper.Profile
{
/// <summary>
/// 构造函数
/// </summary>
public MyProfile()
{
// 配置 mapping 规则
//<源对象,目标对象> 实现从 源对象 到 目标对象 的实体映射
CreateMap<Student, V_Student>()
.ForMember(destination => destination.UUID, opt => opt.Ignore()) //不对UUID进行映射
.ForMember(destination => destination.TecCounts, opt => opt.MapFrom(source => source.Tecs.Count)); //指明来源
}
}

来看下调试结果:

可以发现映射得到的对象v_model_s中的TecCounts值从0变成1了。

3、ForMember方法不仅可以进行指定不同名称的字段进行转换,也可以通过编写规则来实现字段类型的转换。

例如,我们Student(PO)类中的Birthday是DateTime类型的,我们需要通过编写规则将该字段对应到V_Student (VO)类中string类型的Birthday字段上。

修改映射规则如下:

using System;
using System.Collections.Generic;
using TianYa.DotNetShare.Model;
using TianYa.DotNetShare.Model.ViewModel;
using AutoMapper; namespace TianYa.DotNetShare.Service.AutoMapperConfig
{
/// <summary>
/// 实体映射配置类
/// </summary>
public class MyProfile : AutoMapper.Profile
{
/// <summary>
/// 构造函数
/// </summary>
public MyProfile()
{
// 配置 mapping 规则
//<源对象,目标对象> 实现从 源对象 到 目标对象 的实体映射
CreateMap<Student, V_Student>()
.ForMember(destination => destination.UUID, opt => opt.Ignore()) //不对UUID进行映射
.ForMember(destination => destination.TecCounts, opt => opt.MapFrom(source => source.Tecs.Count)) //指明来源
.ForMember(destination => destination.Birthday, opt => opt.ConvertUsing(new DateTimeConverter())); //类型转换
}
} /// <summary>
/// 将DateTime类型转成string类型
/// </summary>
public class DateTimeConverter : IValueConverter<DateTime, string>
{
//实现接口
public string Convert(DateTime source, ResolutionContext context)
=> source.ToString("yyyy年MM月dd日");
}
}

来看下调试结果:

从调试结果可以发现映射成功了。当然我们的ForMember还有很多用法,此处就不再进行描述了,有兴趣的可以自己去进一步了解。

下面我们针对AutoMapper依赖注入再补充一种用法,如下所示:

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Extensions.DependencyInjection;
using AutoMapper;
using TianYa.DotNetShare.Model;
using TianYa.DotNetShare.Model.ViewModel; namespace TianYa.DotNetShare.AutoMapperDemo.Models
{
/// <summary>
/// AutoMapper配置
/// </summary>
public static class AutoMapperConfig
{
/// <summary>
/// AutoMapper依赖注入
/// </summary>
/// <param name="service">服务</param>
public static void AddAutoMapperService(this IServiceCollection service)
{
//注入AutoMapper
service.AddSingleton<IMapper>(new Mapper(new MapperConfiguration(cfg =>
{
// 配置 mapping 规则
//<源对象,目标对象> 实现从 源对象 到 目标对象 的实体映射
cfg.CreateMap<Student, V_Student>()
.ForMember(destination => destination.UUID, opt => opt.Ignore()) //不对UUID进行映射
.ForMember(destination => destination.TecCounts, opt => opt.MapFrom(source => source.Tecs.Count)) //指明来源
.ForMember(destination => destination.Birthday, opt => opt.ConvertUsing(new DateTimeConverter())); //类型转换
})));
}
} /// <summary>
/// 将DateTime类型转成string类型
/// </summary>
public class DateTimeConverter : IValueConverter<DateTime, string>
{
//实现接口
public string Convert(DateTime source, ResolutionContext context)
=> source.ToString("yyyy年MM月dd日");
}
}

然后打开我们的Startup.cs文件进行注入工作,如下所示:

public void ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
}); services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2); //DI依赖注入,批量注入指定的程序集
services.RegisterTianYaSharpService(new string[] { "TianYa.DotNetShare.Repository", "TianYa.DotNetShare.Service" });
//注入AutoMapper映射规则
//services.RegisterAutoMapperProfiles(typeof(MyProfile)); //如果MyProfile写在Web项目中可通过该方式注入AutoMapper映射规则
//services.RegisterAutoMapperProfiles(new string[] { "TianYa.DotNetShare.Service" });
services.AddAutoMapperService();
}

以上的这种AutoMapper依赖注入方式也是可以的。

至此,本章就介绍完了,如果你觉得这篇文章对你有所帮助请记得点赞哦,谢谢!!!

demo源码:

链接:https://pan.baidu.com/s/1axJhWD5alrTAawSwEWJTVA
提取码:00z5

参考博文:https://www.cnblogs.com/danvic712/p/11628523.html

版权声明:如有雷同纯属巧合,如有侵权请及时联系本人修改,谢谢!!!

ASP.NET Core Web 应用程序系列(五)- 在ASP.NET Core中使用AutoMapper进行实体映射的更多相关文章

  1. ASP.NET Core Web 应用程序系列(一)- 使用ASP.NET Core内置的IoC容器DI进行批量依赖注入(MVC当中应用)

    在正式进入主题之前我们来看下几个概念: 一.依赖倒置 依赖倒置是编程五大原则之一,即: 1.上层模块不应该依赖于下层模块,它们共同依赖于一个抽象. 2.抽象不能依赖于具体,具体依赖于抽象. 其中上层就 ...

  2. ASP.NET Core Web 应用程序系列(三)- 在ASP.NET Core中使用Autofac替换自带DI进行构造函数和属性的批量依赖注入(MVC当中应用)

    在上一章中主要和大家分享了在ASP.NET Core中如何使用Autofac替换自带DI进行构造函数的批量依赖注入,本章将和大家继续分享如何使之能够同时支持属性的批量依赖注入. 约定: 1.仓储层接口 ...

  3. ASP.NET Core Web 应用程序系列(二)- 在ASP.NET Core中使用Autofac替换自带DI进行批量依赖注入(MVC当中应用)

    在上一章中主要和大家分享在MVC当中如何使用ASP.NET Core内置的DI进行批量依赖注入,本章将继续和大家分享在ASP.NET Core中如何使用Autofac替换自带DI进行批量依赖注入. P ...

  4. 在 ASP.NET Core 项目中使用 AutoMapper 进行实体映射

    一.前言 在实际项目开发过程中,我们使用到的各种 ORM 组件都可以很便捷的将我们获取到的数据绑定到对应的 List<T> 集合中,因为我们最终想要在页面上展示的数据与数据库实体类之间可能 ...

  5. ASP.NET Core Web 应用程序系列(四)- ASP.NET Core 异步编程之async await

    PS:异步编程的本质就是新开任务线程来处理. 约定:异步的方法名均以Async结尾. 实际上呢,异步编程就是通过Task.Run()来实现的. 了解线程的人都知道,新开一个线程来处理事务这个很常见,但 ...

  6. Asp.Net Core Web应用程序—探索

    前言 作为一个Windows系统下的开发者,我对于Core的使用机会几乎为0,但是考虑到微软的战略规划,我觉得,Core还是有先了解起来的必要. 因为,目前微软已经搞出了两个框架了,一个是Net标准( ...

  7. 使用docker部署Asp.net core web应用程序

    拉取aspnetcore最新docker镜像 aspnetcore的docker镜像在docker官网是有的,是由微软提供的.它的依赖镜像是microsoft/dotnet.通过访问网址:https: ...

  8. ASP.NET Core Web 应用程序开发期间部署到IIS自定义主机域名并附加到进程调试

    想必大家之前在进行ASP.NET Web 应用程序开发期间都有用到过将我们的网站部署到IIS自定义主机域名并附加到进程进行调试. 那我们的ASP.NET Core Web 应用程序又是如何部署到我们的 ...

  9. 循序渐进学.Net Core Web Api开发系列【7】:项目发布到CentOS7

    系列目录 循序渐进学.Net Core Web Api开发系列目录 本系列涉及到的源码下载地址:https://github.com/seabluescn/Blog_WebApi 一.概述 本篇讨论如 ...

随机推荐

  1. 一条Top10热销品牌MySQL语句

    表t_alibaba_data的数据结构如下: 各列含义分别是: 用户id(user_id),品牌id(brand_id),用户行为(type, 其中,点击为0,购买为1,加入收藏为2,加入购物车为3 ...

  2. 学习go语言第二天-变量、常量

    编写测试程序 源码文件以_test结尾;例如:xxx_test.go 测试方法名以Test开头;例如:func TestXXXXX(t *testing.T){} 实现斐波那且数列 package f ...

  3. nbuoj2784 倒水

    题目:http://www.nbuoj.com/v8.83/Problems/Problem.php?pid=2784 一天,TJ买了N个容量无限大的瓶子,开始时每个瓶子里有1升水.接着TJ决定只保留 ...

  4. 2018 牛客国庆集训派对Day4 - H 树链博弈

    链接:https://ac.nowcoder.com/acm/contest/204/H来源:牛客网 题目描述 给定一棵 n 个点的树,其中 1 号结点是根,每个结点要么是黑色要么是白色 现在小 Bo ...

  5. 2018HDU多校二 -F 题 Naive Operations(线段树)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6315 In a galaxy far, far away, there are two integer ...

  6. HDU4109-instruction agreement(差分约束-最长路+建立源点,汇点)

    Ali has taken the Computer Organization and Architecture course this term. He learned that there may ...

  7. linux 安装jmeter

    一 下载jdk sudo apt install oracle-java8-installer 二 网站下载 jmeter 三 对jmeter文件夹 赋权 我都是777 chmod -R 777 ap ...

  8. jumpserver跳板机搭建,适合centos6和centos7的使用

    第17章 jumpserver的搭建   17.1 jumpserver的介绍 jumpserver是全球首款开源的堡垒机,使用的是GNU,GPL的开源协议. jumpserver是用python和g ...

  9. 搭建本地YUM仓库

    YUM介绍 yum(yellow dog updater modified)为多个Linux发行版的软件包管理工具,Redhat RHEL CentOS Fedora YUM主要用于自动安装,升级rp ...

  10. .net core 微服务通讯组件Orleans的使用与配置

    Orleans非常好用 并且支持.net core 社区也非常活跃 Orleans2.0+在国内的教程偏少 多数是1.5版本的教程 在这里写上四篇Orleans教程 目录 1.Orleans的入门教程 ...