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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM