1.在Util类库下新建DIService类
/// <summary> /// 创建一个类,对应在配置文件中配置的DIServices里面的对象的 key /// </summary> public class DIService { public string InterfaceType { get; set; } public string ImplementationType { get; set; } }
2 在webapi的appsettings.json文件中配置 要依赖注入的 接口和实现类
3 为Util类库项目 nuget安装 Unity.Container和Unity.Servicelocator两个包
4.创建服务定位器 ServiceLocator类
namespace Util { public class ServiceLocator : IServiceProvider//IServiceProvider 这个接口是系统自带的 { private readonly IUnityContainer container; public ServiceLocator() { container = new UnityContainer(); //要使用JObject 必须安装 Newtonsoft.Json 包 //读取配置文件 得到一个json对象 var jsonServices = JObject.Parse(File.ReadAllText("appsettings.json"))["DIServices"]; //将上面的jsonServices 转成List<DIService>的集合 var requestServices = JsonConvert.DeserializeObject<List<DIService>>(jsonServices.ToString()); //遍历服务对象 foreach (var requestService in requestServices) { //向容器中注册 container.RegisterType(Type.GetType(requestService.InterfaceType), Type.GetType(requestService.ImplementationType)); } } public T GetService<T>() { return container.Resolve<T>(); } //下面这个方法是IServiceProvider接口要求实现的 public object GetService(Type serviceType) { return container.Resolve(serviceType); } public T GetService<T>(ParameterOverrides parameters) { return container.Resolve<T>(parameters); } } }
5 使用服务定位器 实践依赖注入
namespace Product.WebApi.Controllers { [Produces("application/json")] [Route("api/Product")] public class ProductController : Controller { //这个无参构造函数一旦执行 就完成了接口和实现的映射 ServiceLocator serviceLocator = new ServiceLocator(); [HttpPost] [Route("AddProduct")] public ResultEntity<bool> AddProduct([FromBody] AddProductSPUDto addProductSPUDto) { var result = new ResultEntity<bool>(); //var productdbcontext =new ProductEFCoreContext(); //var irepsotory = new EFCoreRepository(productdbcontext); //var iproductrepsitory = new ProductEFCoreRepository(productdbcontext); var productdbcontext = serviceLocator.GetService<IProductContext>(); //下面 new Unity.Resolution.ParameterOverrides() { { "context", productdbcontext } } //{ }里面还有{ }是因为这是个parameters 说明可能有多个参数对象 //{ "context", productdbcontext } 第一个context是因为 public EFCoreRepository(DbContext context) 的形参 是context //值就是咱们上面要传进去的 productdbcontext var irepsotory = serviceLocator.GetService<IRepository>(new Unity.Resolution.ParameterOverrides() { { "context", productdbcontext } }); var iproductrepsitory = serviceLocator.GetService<IProductRepository>(new Unity.Resolution.ParameterOverrides() { { "context", productdbcontext } }); var addproductspuusecase = new AddProductSPUUseCase(irepsotory, iproductrepsitory); try { result = addproductspuusecase.AddProduct(addProductSPUDto); result.IsSuccess = true; result.count = 1; result.Msg = "上架产品成功"; } catch (Exception ex) { result.ErrorCode = 100; result.Msg = ex.Message; } return result; } } }
unity使用注意点:
依赖中有依赖 参数名字一定要正确 这点很容易错