上一节我们讲到实体,仓储接口和仓储接口的实现需要遵循约定的命名规范,不仅是规范,而且为了依赖注入,现在我们实现仓储的依赖注入

在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架构搭建(四):仓储的依赖注入的更多相关文章

  1. NetCore+Dapper WebApi架构搭建(三):添加实体和仓储

    上一节讲了类库添加一些底层的基本封装,下面来添加实体和仓储 1.Entities文件夹添加一个实体类Users,继承BaseModel,即拥有BaseModel的主键 using System; na ...

  2. NetCore+Dapper WebApi架构搭建(五):Swagger构建WebApi界面

    上一节讲解了仓储的依赖注入,想必现在都可以通过构造函数依赖注入直接调用 但是WebApi只是提供一个接口调用,为了方便我们的操作,我们得给他加上一个图形化界面工具,使用Swagger WebApi项目 ...

  3. NetCore+Dapper WebApi架构搭建(一):基本框架

    初衷是想用dapper搭建一个高性能的架构,因为dapper操作数据库的效率很高 1.VS创建一个NetCore WebApi的框架,然后解决方案添加一个NetStandard的类库 整个解决方案如图 ...

  4. NetCore+Dapper WebApi架构搭建(二):底层封装

    看下我们上一节搭建的架构,现在开始从事底层的封装 1.首先需要一个实体的接口IEntity namespace Dinner.Dapper { public interface IEntity< ...

  5. NetCore+Dapper WebApi架构搭建(六):添加JWT认证

    WebApi必须保证安全,现在来添加JWT认证 1.打开appsettings.json添加JWT认证的配置信息 2.在项目根目录下新建一个Models文件夹,添加一个JwtSettings.cs的实 ...

  6. .Net Core MVC 网站开发(Ninesky) 2.3、项目架构调整-控制反转和依赖注入的使用

    再次调整项目架构是因为和群友dezhou的一次聊天,我原来的想法是项目尽量做简单点别搞太复杂了,仅使用了DbContext的注入,其他的也没有写接口耦合度很高.和dezhou聊过之后我仔细考虑了一下, ...

  7. 【架构师之路】依赖注入原理---IoC框架

    1 IoC理论的背景    我们都知道,在采用面向对象方法设计的软件系统中,它的底层实现都是由N个对象组成的,所有的对象通过彼此的合作,最终实现系统的业务逻辑.  图1:软件系统中耦合的对象 如果我们 ...

  8. 转载:【架构师之路】依赖注入原理---IoC框架

    原文地址:http://www.cnblogs.com/jhli/p/6019895.html 1 IoC理论的背景     我们都知道,在采用面向对象方法设计的软件系统中,它的底层实现都是由N个对象 ...

  9. 使用Visual Studio Code开发Asp.Net Core WebApi学习笔记(六)-- 依赖注入

    本篇将介绍Asp.Net Core中一个非常重要的特性:依赖注入,并展示其简单用法. 第一部分.概念介绍 Dependency Injection:又称依赖注入,简称DI.在以前的开发方式中,层与层之 ...

随机推荐

  1. 20155226 2016-2017-2 《Java程序设计》第5周学习总结

    20155226 2016-2017-2 <Java程序设计>第5周学习总结 教材学习内容总结 语法与继承构架 我们之前接触到的C通常都是将程序流程和错误处理混在一起,在编写程序的时候必须 ...

  2. iOS6下实现滑动返回

    [转载请注明出处] 之前在看iOS7滑动返回时,发现了一个iOS6 SDK下的第三方实现,今天偶然间发现了作者在其博客上对该实现的一些心得,读来深觉之前的思考太过肤浅,许多实际的问题没有考虑到.帖子链 ...

  3. Git 创建仓库【转】

    转自:http://www.runoob.com/git/git-create-repository.html Git 创建仓库 本章节我们将为大家介绍如何创建一个 Git 仓库. 你可以使用一个已经 ...

  4. 那些代表性的HTTP状态码,你还只知道404吗?快来看看吧【转】

    前言 在网络上发送请求后,经常会根据请求的状态码去判断请求的成功失败与否,常见的状态码有200,404,500. 不过你以为HTTP请求的状态码就只有这么几个么?其实是远远比这个多的. 今天这篇文章我 ...

  5. Html.DropDownListFor() 二级联动 ($.getJSON)

    Control: public ActionResult GetPositionName(int parentid) //发布新职位页面中的根据职位类别,获取职位名称 { List<Catego ...

  6. python socket编程和黏包问题

    一.基于TCP的socket tcp是基于链接的,必须先启动服务端,然后再启动客户端去链接服务端,有顺序,不重复,可靠.不会被加上数据边界. server端 import socket sk = so ...

  7. 十五、springboot集成定时任务(Scheduling Tasks)(二)之(线程配置)

    配置类: /** * 定时任务线程配置 * */ @Configuration public class SchedulerConfig implements SchedulingConfigurer ...

  8. dragstart drag dragend dragenter dragover dragleave drop

    dragstart drag dragend dragenter dragover dragleave drop   前端框架层出不穷,网页上的效果越来越绚丽,制作绚丽的效果的成本越来越低,其中有种拖 ...

  9. 如何查看页面是否开启了gzip压缩

    1.谷歌浏览器 F12 2.在表头单击鼠标右键 3.如果开启了gzip则显示gzip,没有则是空

  10. git —— pycharm+git管理/编辑项目

    pycharm+git  管理/编辑项目 一.pycharm中配置github 二.配置git 并不是配置了GitHub就可以的.还需要配置一下Git 前提是本地中已经安装了git 三.把本地项目上传 ...