NopCommerce源码架构详解-EF数据访问实例详解

今天我来分析一下nop里面怎么访问数据库,我们知道Nop里面的ORM是使用的EF并采用的仓储Repository模式。

NopCommerce源码架构详解概述

文章目录

概述

NopCommerce源码架构详解-EF数据访问实例详解。

内容

今天我来分析一下nop里面怎么访问数据库,我们知道Nop里面的ORM是使用的EF并采用的仓储Repository模式。

1、IRepository

首先,Nop定义了一个通用的泛型接口:

Nop.Core.Data.IRepository

2020-04-23-20-41-42

里面定义了常用的增、删、查、改等操作方法,但是由于是接口,只是方法定义没有实现。

声明成泛型的好处只用定义一些通用的方法,这样可以适用于所有的表。而不用每一个表单独定义一个类重复这些增、删、查、改方法。

2、EfRepository

Nop.Data.EfRepository就是上面接口Nop.Core.Data.IRepository的EF具体实现。

2020-04-23-20-41-48

可以看到使用了EF相关的API,比如:DbContext,DbSet等,下面我具体来看一下插入、添加一条记录的方法:

2020-04-23-20-41-54

3、依赖注入

Nop里面代码到处都充分体现了面向接口编程,所有代码你F12跟踪进去都是只定位到对应的接口。

查看Controller代码看到Controller引用是都是Service的接口,如图:

2020-04-23-20-42-01

Nop里是通过Autofac对mvc的Controller进行依赖注入的。

这个时候我们要看这些Service接口的具体实现才能找到其“庐山真面目”。

我们随便找一个Service具体实现

UrlRecordService的一些方法:

public virtual UrlRecord GetBySlug(string slug)
{
    if (String.IsNullOrEmpty(slug))
        return null;

    var query = from ur in _urlRecordRepository.Table
                where ur.Slug == slug
                //first, try to find an active record
                orderby ur.IsActive descending, ur.Id
                select ur;
    var urlRecord = query.FirstOrDefault();
    return urlRecord;
}

public virtual UrlRecordForCaching GetBySlugCached(string slug)
{
    if (String.IsNullOrEmpty(slug))
        return null;

    if (_localizationSettings.LoadAllUrlRecordsOnStartup)
    {
        //获取已缓存全部Url记录数据 
        var source = GetAllUrlRecordsCached();
        var query = from ur in source
                    where ur.Slug.Equals(slug, StringComparison.InvariantCultureIgnoreCase)
                    //first, try to find an active record
                    orderby ur.IsActive descending, ur.Id
                    select ur;
        var urlRecordForCaching = query.FirstOrDefault();
        return urlRecordForCaching;
    }

    //gradual loading
    string key = string.Format(URLRECORD_BY_SLUG_KEY, slug);
    return _cacheManager.Get(key, () =>
    {
        var urlRecord = GetBySlug(slug);
        if (urlRecord == null)
            return null;

        var urlRecordForCaching = Map(urlRecord);
        return urlRecordForCaching;
    });
}

/// <summary>
/// Gets all cached URL records
/// </summary>
/// <returns>cached URL records</returns>
protected virtual IList<UrlRecordForCaching> GetAllUrlRecordsCached()
{
    //cache
    string key = string.Format(URLRECORD_ALL_KEY);
    return _cacheManager.Get(key, () =>
    {
        var query = from ur in _urlRecordRepository.Table
                    select ur;
        var urlRecords = query.ToList();
        var list = new List<UrlRecordForCaching>();
        foreach (var ur in urlRecords)
        {
            var urlRecordForCaching = Map(ur);
            list.Add(urlRecordForCaching);
        }
        return list;
    });
}

可以从上面代码看到上面通过Repository.Table和linq来获取数据的。上面有用到Nop的缓存管理cacheManager,我们再回过头来看看.Table是什么? 在接口Nop.Core.Data.IRepository里面

2020-04-23-20-42-10

然后我们再来看接口的实现Nop.Data.EfRepository对应的实现:

2020-04-23-20-42-15

可以看到采用的EF的的DbSet返回表的数据,对使用过EF的同学都不用我再解释了吧?

上面我们有说Controller引用的IXXXService接口,而IXXXService接口的具体实现XXXXXXService又是引用的IXXXRepository接口,IXXXRepository接口具体实现是XXXRepository。

不同表,T就相应不同,比如UrlRecordService里面Repository。

2020-04-23-20-42-20

最后,Nop里面又怎么设置Nop.Core.Data.IRepository使用是Nop.Data.EfRepository呢?

在项目Nop.Web.Framework里面有一个类DependencyRegistrar专门告诉Autofac依赖注册的。

2020-04-23-20-42-26

在DependencyRegistrar类里面我们可以找到以下代码:

2020-04-23-20-42-32

通过builder.RegisterGeneric可以注册泛型依赖。同理你要可以在这个类里面找到IXXXService的依赖注入。

到此,Nop的使用EF访问数据库就来龙去脉已经清楚,现在你可以打开代码自己DIY。

原文出处:蓝狐软件工作室【蓝狐】

原文链接:http://m.lanhusoft.com/Article/349.html

本文观点不代表 .Net中文网 立场,转载请联系原作者。

发表评论

登录后才能评论