zoukankan      html  css  js  c++  java
  • NetCore+Dapper WebApi架构搭建(四):仓储的依赖注入

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

    在NetCore WebApi项目中新添加一个文件夹(Unit),当然你也可以直接放在根目录下面,关键是后期类增加了你会找对地方,看起来不是那么乱,添加一个RuntimeHelper

    我先说一下实现仓储依赖注入的基本思路,就是通过反射获取所有的程序集,然后在程序集中找到 I+实体+Repository的接口和 实体+Repository的实现类,然后在依赖注入容器中注册他们的对应关系

    所以这个RuntimeHelper很明显是通过反射获取程序集使用的

     1 using Microsoft.AspNetCore.Mvc;
     2 using Microsoft.Extensions.DependencyModel;
     3 using System;
     4 using System.Collections.Generic;
     5 using System.Linq;
     6 using System.Reflection;
     7 using System.Runtime.Loader;
     8 
     9 namespace Dinner.WebApi.Unit
    10 {
    11     [ApiExplorerSettings(IgnoreApi=true)]
    12     public class RuntimeHelper
    13     {
    14         /// <summary>
    15         /// 获取项目程序集,排除所有的系统程序集(Microsoft.***、System.***等)、Nuget下载包
    16         /// </summary>
    17         /// <returns></returns>
    18         public static IList<Assembly> GetAllAssemblies()
    19         {
    20             List<Assembly> list = new List<Assembly>();
    21             var deps = DependencyContext.Default;
    22             //排除所有的系统程序集、Nuget下载包
    23             var libs = deps.CompileLibraries.Where(lib => !lib.Serviceable && lib.Type != "package");
    24             foreach (var lib in libs)
    25             {
    26                 try
    27                 {
    28                     var assembly = AssemblyLoadContext.Default.LoadFromAssemblyName(new AssemblyName(lib.Name));
    29                     list.Add(assembly);
    30                 }
    31                 catch (Exception ex)
    32                 {
    33                     //
    34                 }
    35             }
    36             return list;
    37         }
    38 
    39         public static Assembly GetAssembly(string assemblyName)
    40         {
    41             return GetAllAssemblies().FirstOrDefault(f => f.FullName.Contains(assemblyName));
    42         }
    43 
    44         public static IList<Type> GetAllTypes()
    45         {
    46             List<Type> list = new List<Type>();
    47             foreach (var assembly in GetAllAssemblies())
    48             {
    49                 var typeinfos = assembly.DefinedTypes;
    50                 foreach (var typeinfo in typeinfos)
    51                 {
    52                     list.Add(typeinfo.AsType());
    53                 }
    54             }
    55             return list;
    56         }
    57 
    58         /// <summary>
    59         /// 根据AssemblyName获取所有的类
    60         /// </summary>
    61         /// <param name="assemblyName"></param>
    62         /// <returns></returns>
    63         public static IList<Type> GetTypesByAssembly(string assemblyName)
    64         {
    65             List<Type> list = new List<Type>();
    66             var assembly = AssemblyLoadContext.Default.LoadFromAssemblyName(new AssemblyName(assemblyName));
    67             var typeinfos = assembly.DefinedTypes;
    68             foreach (var typeinfo in typeinfos)
    69             {
    70                 list.Add(typeinfo.AsType());
    71             }
    72             return list;
    73         }
    74 
    75         public static Type GetImplementType(string typeName, Type baseInterfaceType)
    76         {
    77             return GetAllTypes().FirstOrDefault(t =>
    78             {
    79                 if (t.Name == typeName && t.GetTypeInfo().GetInterfaces().Any(b => b.Name == baseInterfaceType.Name))
    80                 {
    81                     var typeinfo = t.GetTypeInfo();
    82                     return typeinfo.IsClass && !typeinfo.IsAbstract && !typeinfo.IsGenericType;
    83                 }
    84                 return false;
    85             });
    86         }
    87     }
    88 }
    View Code

    上面的那个[ApiExplorerSettings(IgnoreApi=true)]是使用Swagger时使用的,这个我们后面会讲

    上面的类就是是反射对程序集的操作

    这个我们要使用第三方的Autofac依赖注入框架,所以先引入Nuget包:Autofac.Configuration和Autofac.Extensions.DependencyInjection

    下面打开startUp.cs类

    先把ConfigureServices方法的返回值由void变为IServiceProvider

    然后在ConfigureServices的AddMvc()之后添加下面代码

     1 #region 依赖注入
     2 
     3             var builder = new ContainerBuilder();//实例化容器
     4             //注册所有模块module
     5             builder.RegisterAssemblyModules(Assembly.GetExecutingAssembly());
     6             //获取所有的程序集
     7             //var assemblys = BuildManager.GetReferencedAssemblies().Cast<Assembly>().ToArray();
     8             var assemblys = RuntimeHelper.GetAllAssemblies().ToArray();
     9 
    10             //注册所有继承IDependency接口的类
    11             builder.RegisterAssemblyTypes().Where(type => typeof(IDependency).IsAssignableFrom(type) && !type.IsAbstract);
    12             //注册仓储,所有IRepository接口到Repository的映射
    13             builder.RegisterAssemblyTypes(assemblys).Where(t => t.Name.EndsWith("Repository") && !t.Name.StartsWith("I")).AsImplementedInterfaces();
    14             //注册服务,所有IApplicationService到ApplicationService的映射
    15             //builder.RegisterAssemblyTypes(assemblys).Where(t => t.Name.EndsWith("AppService") && !t.Name.StartsWith("I")).AsImplementedInterfaces();
    16             builder.Populate(services);
    17             ApplicationContainer = builder.Build();
    18 
    19             return new AutofacServiceProvider(ApplicationContainer); //第三方IOC接管 core内置DI容器 
    20             //return services.BuilderInterceptableServiceProvider(builder => builder.SetDynamicProxyFactory());
    21             #endregion
    View Code

    这样以来注入就可以了

    现在添加一个UsersController进行测试

     1 using Dinner.Dapper.Entities;
     2 using Dinner.Dapper.IRepository;
     3 using Microsoft.AspNetCore.Mvc;
     4 using System;
     5 using System.Collections.Generic;
     6 using System.Threading.Tasks;
     7 
     8 namespace Dinner.WebApi.Controllers
     9 {
    10 
    11     [Route("api/[controller]/[action]")]
    12     public class UsersController : Controller
    13     {
    14         private readonly IUserRepository userRepository;
    15         public UsersController(IUserRepository _userRepository)
    16         {
    17             userRepository = _userRepository;
    18         }
    19 
    20         /// <summary>
    21         /// 获取所有用户
    22         /// </summary>
    23         /// <returns></returns>
    24         /// 
    25         [HttpGet]
    26         public async Task<JsonResult> GetUsers()
    27         {
    28             List<Users> list = await userRepository.GetUsers();
    29             return Json(list);
    30         }
    31 
    32         /// <summary>
    33         /// 新增用户
    34         /// </summary>
    35         /// <param name="entity"></param>
    36         /// <returns></returns>
    37         [HttpPost]
    38         public async Task PostUser(Users entity)
    39         {
    40             entity.Password = Dapper.Helpers.Encrypt.Md5(entity.Password).ToUpper();
    41             await userRepository.PostUser(entity);
    42         }
    43 
    44         /// <summary>
    45         /// 修改用户信息
    46         /// </summary>
    47         /// <param name="entity"></param>
    48         /// <returns></returns>
    49         [HttpPut]
    50         public async Task PutUser(Users entity)
    51         {
    52             try
    53             {
    54                 entity.Password = Dapper.Helpers.Encrypt.Md5(entity.Password).ToUpper();
    55                 await userRepository.PutUser(entity);
    56             }
    57             catch (Exception ex)
    58             {
    59                 throw new ArgumentException(ex.Message);
    60             }
    61         }
    62 
    63         /// <summary>
    64         /// 删除用户
    65         /// </summary>
    66         /// <param name="Id"></param>
    67         /// <returns></returns>
    68         [HttpDelete]
    69         public async Task DeleteUser(Guid Id)
    70         {
    71             try
    72             {
    73                 await userRepository.DeleteUser(Id);
    74             }
    75             catch (Exception ex)
    76             {
    77                 throw new ArgumentException(ex.Message);
    78             }
    79         }
    80     }
    81 }
    View Code

    自己测试一下仓储的增删改查吧,看看写的有问题没有

    下一节我们讲解Swagger构建WebApi界面

    赠送一个Framework版本的依赖注入

     1 #region autofac IOC容器配置
     2             var builder = new ContainerBuilder();
     3 
     4             //注册所有的controller
     5             builder.RegisterControllers(typeof(MvcApplication).Assembly).PropertiesAutowired();
     6             //注册所有模块module
     7             builder.RegisterAssemblyModules(Assembly.GetExecutingAssembly());
     8 
     9             var assemblys = BuildManager.GetReferencedAssemblies().Cast<Assembly>().ToArray();
    10 
    11             //注册所有继承IDependency接口的类
    12             builder.RegisterAssemblyTypes(assemblys)
    13             .Where(type => typeof(IDependency).IsAssignableFrom(type) && !type.IsAbstract);
    14 
    15             //注册服务,所有IxxxxRepository=>xxxxRepository
    16             builder.RegisterAssemblyTypes(assemblys).Where(t => t.Name.EndsWith("Repository") && !t.Name.StartsWith("I")).AsImplementedInterfaces();
    17           
    18             var container = builder.Build();
    19 
    20             BaseInfo._container = container;
    21 
    22             DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
    23             #endregion
    View Code

    源码地址: https://github.com/wangyulong0505/Dinner

  • 相关阅读:
    ASP.NET中的特殊路径标识"~"
    ASP.NET中的Request、Response、Server对象
    XSS漏洞(跨站脚本)
    WEB开发原则
    HTTP协议
    【原】从零开始改造淘淘商城(引入dubbo解决项目耦合)02
    【转】Nginx的启动、停止与重启
    【原】spring boot添加cros全局过滤器
    【转】Swagger2 添加HTTP head参数
    【原】Spring Boot 配置swagger2没有文档解决方案
  • 原文地址:https://www.cnblogs.com/wangyulong/p/8961301.html
Copyright © 2011-2022 走看看