NopCommerce用.net core重写ef

最近看了NopCommerce源码,用core学习着写了一个项目,修改的地方记录下。项目地址

NopCommerce框架出来好久了。18年的第一季度 懒加载出来后也会全部移动到.net core。那么就更好玩了。


  项目内容

  1. 模仿部分
    1. 分层模式
    2. 引擎机制
    3. DI容器
    4. EF
    5. 仓储模式
    6. Mapping
  2. 部分修改
    1. .net core 重写类库
    2. EFcore mysql 动态加载dbset

当然NopCommerce还包含很多特技:Plugin,Seo,订阅发布,theme切换等等。这些后期再维护进去。


项目介绍

  1. 项目分层

    NopCommerce用.net core重写ef

    1. 1、Libraries

        Nop.Core:【核心层】基础设施,例:领域对象,仓库接口,引擎接口,DI管理接口,反射,公共方法。

        Nop.Data:【数据层】EF相关,dbcontext,仓储实现,mapping

        Nop.Services:【服务层】数据逻辑处理由这层提供。

    1. 2、Presentation

        Nop.Web:【页面层】展示界面。

        Nop.Web.Framework:【页面基础层】web层的上层封装。例如启动项的实现,DI实现。

详细的分层思想和细节这里不再复述。

    2.项目修改点

  EF6转换到EFCore,数据库选择mysql,动态加载dbset 看了相关代码,在进行解释    

     public class DataBaseStartup: ISelfStartup
{ public void ConfigureServices(IServiceCollection services, IConfigurationRoot configuration)
{
services.AddDbContext<SelfDbContext>(x => x.UseMySql(configuration.GetConnectionString("MySql")));
} public void Configure(IApplicationBuilder application)
{
var dbContext=EngineContext.Current.ServiceProvider.GetService<SelfDbContext>();
dbContext.Database.EnsureCreated();
} public int Order { get; } = ;
}
    public SelfDbContext(DbContextOptions options) : base(options)
{ }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.AddEntityConfigurationsFromAssembly(GetType().Assembly);
base.OnModelCreating(modelBuilder);
}
     public static class ModelBuilderExtenions
{
private static IEnumerable<Type> GetMappingTypes(this Assembly assembly, Type mappingInterface)
{
return assembly.GetTypes().Where(x => !x.IsAbstract && !x.IsGenericType && !x.IsInterface && x.GetInterfaces().Any(y => y == mappingInterface));
} public static void AddEntityConfigurationsFromAssembly(this ModelBuilder modelBuilder, Assembly assembly)
{
var mappingTypes = assembly.GetMappingTypes(typeof(ISelfEntityMappingConfiguration));
foreach (var config in mappingTypes.Select(Activator.CreateInstance).Cast<ISelfEntityMappingConfiguration>())
{
config.Map(modelBuilder);
}
}
}
     public  class StudentMapping : ISelfEntityMappingConfiguration
{
public void Map(ModelBuilder b)
{
b.Entity<Student>().ToTable("Student")
.HasKey(p => p.Id); b.Entity<Student>().Property(p => p.Class).HasMaxLength().IsRequired();
b.Entity<Student>().Property(p => p.Name).HasMaxLength();
}
}
     public interface ISelfEntityMappingConfiguration
{
void Map(ModelBuilder b);
}
     public class Student:BaseEntity
{
public string Name { get; set; } public string Class { get; set; }
}

      解释:

    1. DataBaseStartup是继承Startup的数据中间件处理类。这里去选择数据库类型和dbcontext,以及数据库初始化。Nopcommerce原先是在install那层判断是否存在数据库json处理数据库初始化,这里简单化了,初始化可以抽象出来再处理。这个类的实现是在web.framwork层。解耦了核心与web层的。这里完全可以自己再重写一个处理类,用来切换数据库等其他操作。
    2. SelfDbContext是数据处理上下文类。以前写的dbcontext处理新增的实体类dbset都是一个一个属性添加,这里是通过反射进行动态加载。相关的方法写在了modelbuilder的扩展方法里面
    3. ModelBuilderExtenions是modelbuilder的构建扩展方法的类。里面介绍如何通过反射查找如要map进入的实体map对象。主要通过对比类型继承的接口对象type
    4. ISelfEntityMappingConfiguration是所有map对象的上层接口,通过这个类的类别判断实体加入到dbcontext
    5. StudentMapping和student类是这里举例的例子。Mapping可以对数据字段进行处理。当然也可以直接在实体类加上attribute。

    3.项目继承nopcommerce的其他地方

    1. 引擎构建。项目中也构建了EngineContext和IEngine。引擎是整个项目启动的处理核心,处理的东西不再复述。发现构建了这个之后 可以切换orm框架了。对于一些大型需要对接第三方同步orm,那么这个构建出来之后就非常好处理了。当然好处的地方还有更多。
    2. 仓储模式。这里其实是伪仓储,封装多出一个仓库管理员,并没有事务聚合根等做法。
    3. DI选择auotofac。
上一篇:N阶台阶问题(详解)


下一篇:HDU 2602 Bone Collector (01背包DP)