NetCore+Dapper WebApi架构搭建(四):仓储的依赖注入
上一节我们讲到实体,仓储接口和仓储接口的实现需要遵循约定的命名规范,不仅是规范,而且为了依赖注入,现在我们实现仓储的依赖注入
在NetCore WebApi项目中新添加一个文件夹(Unit),当然你也可以直接放在根目录下面,关键是后期类增加了你会找对地方,看起来不是那么乱,添加一个RuntimeHelper

我先说一下实现仓储依赖注入的基本思路,就是通过反射获取所有的程序集,然后在程序集中找到 I+实体+Repository的接口和 实体+Repository的实现类,然后在依赖注入容器中注册他们的对应关系
所以这个RuntimeHelper很明显是通过反射获取程序集使用的
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyModel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.Loader; namespace Dinner.WebApi.Unit
{
[ApiExplorerSettings(IgnoreApi=true)]
public class RuntimeHelper
{
/// <summary>
/// 获取项目程序集,排除所有的系统程序集(Microsoft.***、System.***等)、Nuget下载包
/// </summary>
/// <returns></returns>
public static IList<Assembly> GetAllAssemblies()
{
List<Assembly> list = new List<Assembly>();
var deps = DependencyContext.Default;
//排除所有的系统程序集、Nuget下载包
var libs = deps.CompileLibraries.Where(lib => !lib.Serviceable && lib.Type != "package");
foreach (var lib in libs)
{
try
{
var assembly = AssemblyLoadContext.Default.LoadFromAssemblyName(new AssemblyName(lib.Name));
list.Add(assembly);
}
catch (Exception ex)
{
//
}
}
return list;
} public static Assembly GetAssembly(string assemblyName)
{
return GetAllAssemblies().FirstOrDefault(f => f.FullName.Contains(assemblyName));
} public static IList<Type> GetAllTypes()
{
List<Type> list = new List<Type>();
foreach (var assembly in GetAllAssemblies())
{
var typeinfos = assembly.DefinedTypes;
foreach (var typeinfo in typeinfos)
{
list.Add(typeinfo.AsType());
}
}
return list;
} /// <summary>
/// 根据AssemblyName获取所有的类
/// </summary>
/// <param name="assemblyName"></param>
/// <returns></returns>
public static IList<Type> GetTypesByAssembly(string assemblyName)
{
List<Type> list = new List<Type>();
var assembly = AssemblyLoadContext.Default.LoadFromAssemblyName(new AssemblyName(assemblyName));
var typeinfos = assembly.DefinedTypes;
foreach (var typeinfo in typeinfos)
{
list.Add(typeinfo.AsType());
}
return list;
} public static Type GetImplementType(string typeName, Type baseInterfaceType)
{
return GetAllTypes().FirstOrDefault(t =>
{
if (t.Name == typeName && t.GetTypeInfo().GetInterfaces().Any(b => b.Name == baseInterfaceType.Name))
{
var typeinfo = t.GetTypeInfo();
return typeinfo.IsClass && !typeinfo.IsAbstract && !typeinfo.IsGenericType;
}
return false;
});
}
}
}
上面的那个[ApiExplorerSettings(IgnoreApi=true)]是使用Swagger时使用的,这个我们后面会讲
上面的类就是是反射对程序集的操作
这个我们要使用第三方的Autofac依赖注入框架,所以先引入Nuget包:Autofac.Configuration和Autofac.Extensions.DependencyInjection
下面打开startUp.cs类
先把ConfigureServices方法的返回值由void变为IServiceProvider
然后在ConfigureServices的AddMvc()之后添加下面代码
#region 依赖注入
var builder = new ContainerBuilder();//实例化容器
//注册所有模块module
builder.RegisterAssemblyModules(Assembly.GetExecutingAssembly());
//获取所有的程序集
//var assemblys = BuildManager.GetReferencedAssemblies().Cast<Assembly>().ToArray();
var assemblys = RuntimeHelper.GetAllAssemblies().ToArray();
//注册所有继承IDependency接口的类
builder.RegisterAssemblyTypes().Where(type => typeof(IDependency).IsAssignableFrom(type) && !type.IsAbstract);
//注册仓储,所有IRepository接口到Repository的映射
builder.RegisterAssemblyTypes(assemblys).Where(t => t.Name.EndsWith("Repository") && !t.Name.StartsWith("I")).AsImplementedInterfaces();
//注册服务,所有IApplicationService到ApplicationService的映射
//builder.RegisterAssemblyTypes(assemblys).Where(t => t.Name.EndsWith("AppService") && !t.Name.StartsWith("I")).AsImplementedInterfaces();
builder.Populate(services);
ApplicationContainer = builder.Build();
return new AutofacServiceProvider(ApplicationContainer); //第三方IOC接管 core内置DI容器
//return services.BuilderInterceptableServiceProvider(builder => builder.SetDynamicProxyFactory());
#endregion
这样以来注入就可以了
现在添加一个UsersController进行测试
using Dinner.Dapper.Entities;
using Dinner.Dapper.IRepository;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Threading.Tasks; namespace Dinner.WebApi.Controllers
{ [Route("api/[controller]/[action]")]
public class UsersController : Controller
{
private readonly IUserRepository userRepository;
public UsersController(IUserRepository _userRepository)
{
userRepository = _userRepository;
} /// <summary>
/// 获取所有用户
/// </summary>
/// <returns></returns>
///
[HttpGet]
public async Task<JsonResult> GetUsers()
{
List<Users> list = await userRepository.GetUsers();
return Json(list);
} /// <summary>
/// 新增用户
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
[HttpPost]
public async Task PostUser(Users entity)
{
entity.Password = Dapper.Helpers.Encrypt.Md5(entity.Password).ToUpper();
await userRepository.PostUser(entity);
} /// <summary>
/// 修改用户信息
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
[HttpPut]
public async Task PutUser(Users entity)
{
try
{
entity.Password = Dapper.Helpers.Encrypt.Md5(entity.Password).ToUpper();
await userRepository.PutUser(entity);
}
catch (Exception ex)
{
throw new ArgumentException(ex.Message);
}
} /// <summary>
/// 删除用户
/// </summary>
/// <param name="Id"></param>
/// <returns></returns>
[HttpDelete]
public async Task DeleteUser(Guid Id)
{
try
{
await userRepository.DeleteUser(Id);
}
catch (Exception ex)
{
throw new ArgumentException(ex.Message);
}
}
}
}
自己测试一下仓储的增删改查吧,看看写的有问题没有
下一节我们讲解Swagger构建WebApi界面
赠送一个Framework版本的依赖注入
#region autofac IOC容器配置
var builder = new ContainerBuilder(); //注册所有的controller
builder.RegisterControllers(typeof(MvcApplication).Assembly).PropertiesAutowired();
//注册所有模块module
builder.RegisterAssemblyModules(Assembly.GetExecutingAssembly()); var assemblys = BuildManager.GetReferencedAssemblies().Cast<Assembly>().ToArray(); //注册所有继承IDependency接口的类
builder.RegisterAssemblyTypes(assemblys)
.Where(type => typeof(IDependency).IsAssignableFrom(type) && !type.IsAbstract); //注册服务,所有IxxxxRepository=>xxxxRepository
builder.RegisterAssemblyTypes(assemblys).Where(t => t.Name.EndsWith("Repository") && !t.Name.StartsWith("I")).AsImplementedInterfaces(); var container = builder.Build(); BaseInfo._container = container; DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
#endregion
源码地址: https://github.com/wangyulong0505/Dinner
NetCore+Dapper WebApi架构搭建(四):仓储的依赖注入的更多相关文章
- NetCore+Dapper WebApi架构搭建(三):添加实体和仓储
上一节讲了类库添加一些底层的基本封装,下面来添加实体和仓储 1.Entities文件夹添加一个实体类Users,继承BaseModel,即拥有BaseModel的主键 using System; na ...
- NetCore+Dapper WebApi架构搭建(五):Swagger构建WebApi界面
上一节讲解了仓储的依赖注入,想必现在都可以通过构造函数依赖注入直接调用 但是WebApi只是提供一个接口调用,为了方便我们的操作,我们得给他加上一个图形化界面工具,使用Swagger WebApi项目 ...
- NetCore+Dapper WebApi架构搭建(一):基本框架
初衷是想用dapper搭建一个高性能的架构,因为dapper操作数据库的效率很高 1.VS创建一个NetCore WebApi的框架,然后解决方案添加一个NetStandard的类库 整个解决方案如图 ...
- NetCore+Dapper WebApi架构搭建(二):底层封装
看下我们上一节搭建的架构,现在开始从事底层的封装 1.首先需要一个实体的接口IEntity namespace Dinner.Dapper { public interface IEntity< ...
- NetCore+Dapper WebApi架构搭建(六):添加JWT认证
WebApi必须保证安全,现在来添加JWT认证 1.打开appsettings.json添加JWT认证的配置信息 2.在项目根目录下新建一个Models文件夹,添加一个JwtSettings.cs的实 ...
- .Net Core MVC 网站开发(Ninesky) 2.3、项目架构调整-控制反转和依赖注入的使用
再次调整项目架构是因为和群友dezhou的一次聊天,我原来的想法是项目尽量做简单点别搞太复杂了,仅使用了DbContext的注入,其他的也没有写接口耦合度很高.和dezhou聊过之后我仔细考虑了一下, ...
- 【架构师之路】依赖注入原理---IoC框架
1 IoC理论的背景 我们都知道,在采用面向对象方法设计的软件系统中,它的底层实现都是由N个对象组成的,所有的对象通过彼此的合作,最终实现系统的业务逻辑. 图1:软件系统中耦合的对象 如果我们 ...
- 转载:【架构师之路】依赖注入原理---IoC框架
原文地址:http://www.cnblogs.com/jhli/p/6019895.html 1 IoC理论的背景 我们都知道,在采用面向对象方法设计的软件系统中,它的底层实现都是由N个对象 ...
- 使用Visual Studio Code开发Asp.Net Core WebApi学习笔记(六)-- 依赖注入
本篇将介绍Asp.Net Core中一个非常重要的特性:依赖注入,并展示其简单用法. 第一部分.概念介绍 Dependency Injection:又称依赖注入,简称DI.在以前的开发方式中,层与层之 ...
随机推荐
- 漂亮!Javascript代码模仿淘宝宝贝搜索结果的分页显示效果
分页按钮思想: 1.少于9页,全部显示 2.大于9页,1.2页显示,中间页码当前页为中心,前后各留两个页码 先看效果图: 01输入框焦点效果 02效果 模仿淘宝的分页按钮效果控件kkpager JS ...
- HDU1505 City Game 悬线法
题意: 给出一个像这样的矩阵 R F F F F F F F F F F F R R R F F F F F F F F F F F F F F F 求F组成的最大子矩阵(面积最大) 有多组数 ...
- CentOS Linux 7 安装教程
建立新的虚拟机 将CentOS 7 ISO文件插入到CD-Rom 启动虚拟机,F12选择启动方式为CD/DVD 选择Install CentOS Linux 7 加载安装必要文件 选择安装过程所显示的 ...
- 20145202马超 2016-2017-2 《Java程序设计》第三次实验
实验三 敏捷开发与XP实践 http://www.cnblogs.com/rocedu/p/4795776.html, Eclipse的内容替换成IDEA 在IDEA中使用工具(Code->Re ...
- MODULE_DEVICE_TABLE【转】
转自:http://blog.csdn.net/tangkegagalikaiwu/article/details/8444249 This pci_device_id structure needs ...
- Android页面之间进行数据回传
要求:页面1跳转到页面2,页面2再返回页面1同时返回数据 页面1添加如下代码: Intent intent = new Intent(); intent.setClass(页面1.this, 页面2. ...
- Python基础:内置异常(未完待续)
本文根据Python 3.6.5的官文Built-in Exceptions编写,不会很详细,仅对Python的内置异常进行简单(重难点)介绍——很多异常都可以从名称判断出其意义,罗列所有的内置异常. ...
- 监听 手机back键和顶部的回退
// 回退事件,监听 手机back键和顶部的回退 pushHistory(); window.addEventListener("popstate", function(e) { ...
- 忘记SVN密码怎么办
1:下载TSvnPwd.exe 2:使用wireshark抓包.例如: PROPFIND /svn/dev2/!svn/vcc/default HTTP/1.1Host: 192.168.156.1: ...
- 洛谷P1266速度限制
传送门啦 看起来是一个最短路问题,但是引入了速度限制,就要写一下二维最短路了. $ dis[i][j] $ :表示到i这个点,速度为j的最短时间. #include <iostream> ...