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

在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. 七牛云 上传图片 https 修改Nginx 注意事项

    仅在这记录下,今天的事情. 问题出自于Nginx 设置http 强制跳转 https设置 1.上午,出于某些需求,我将服务器Nginx 设置http 强行跳转 https server { liste ...

  2. 【译】第五篇 Integration Services:增量加载-Deleting Rows

    本篇文章是Integration Services系列的第五篇,详细内容请参考原文. 在上一篇你学习了如何将更新从源传送到目标.你同样学习了使用基于集合的更新优化这项功能.回顾增量加载记住,在SSIS ...

  3. 文件操作fstream

    c++文件操作详解 2009-04-16 20:46:35|  分类: C/C++|举报|字号 订阅 C++ 通过以下几个类支持文件的输入输出: ofstream: 写操作(输出)的文件类 (由ost ...

  4. Ubuntu自定义终端窗口位置

    方法一: 自定义终端启动快捷键 具体方法是自定义一个快速启动终端的快捷键,附带设置终端启动时的位置参数.首先获得需要放置窗口的目标位置信息,可以通过终端命令“ xwininfo ”来获得.步骤是首先打 ...

  5. linux 配置免密码登陆

    在使用scp命令传输的时候需要密码 配置免密码登陆 ssh-keygen -t rsa (四个回车) 执行命令完成后,会生成两个文件id_rsa(私钥).id-rsa.pub(公钥) 将公钥拷贝到要免 ...

  6. C#.NET调用WSDL接口及方法

    1.首先需要清楚WSDL的引用地址 如:http://XX.XX.4.146:8089/axis/services/getfileno?wsdl 上述地址的构造为 类名getfileno. 2.在.N ...

  7. Django中cookie和session

    cookie Cookie的由来 大家都知道HTTP协议是无状态的. 无状态的意思是每次请求都是独立的,它的执行情况和结果与前面的请求和之后的请求都无直接关系,它不会受前面的请求响应情况直接影响,也不 ...

  8. RabbitMQ--work queues(二)

    封装一个task到一个message,并发送到queue.consumer会去除task并执行这个task. 这里我们简化了操作,发送消息到队列中,consumer取出消息计算里面'.'号有几个就sl ...

  9. Scrapy的【SitemapSpider】的【官网示例】没有name属性

    Windows 10家庭中文版,Python 3.6.4,Scrapy 1.5.0, 上午看了Scrapy的Spiders官文,并按照其中的SitemapSpider的示例练习,发现官文的示例存在问题 ...

  10. MySQL学习笔记:floor、round —— 取整

    在MySQL中做数值处理,需要取整或者四舍五入. floor:函数只返回整数部分,小数部分舍弃: round:函数四舍五入: END 2018-05-29 11:31:22