使用IOC内置的容器进行属性注入
使用IOC内置的容器进行属性注入,新建Asp Net Core Web项目,添加以下内容
1. 自定义特性,标记需要控制器Controoler中依赖注入的属性标记和对应服务接口
using System; namespace WebAppTest.CustomAttrributes { /// <summary> /// 属性的特性标记,主要用于标记属性 /// </summary> [AttributeUsage(AttributeTargets.Property)] public class CustomPropertyAttribute: Attribute { } /// <summary> /// 方法的特性标记,主要用于标记方法 /// </summary> [AttributeUsage(AttributeTargets.Method)] public class CustomMethodAttribute : Attribute { } }
添加接口
namespace WebAppTest.Services { public interface ITestA { void Show(); } } using System; namespace WebAppTest.Services { public class TestA : ITestA { public void Show() { Console.WriteLine($"这是接口ITestA的实现。。。"); } } }
2. 自定义类实现IOC容器,Controller控制器属性注入和Controller控制器方法注入,CustomMethodAttribute标记需要的方法,不是所有的方法,CustomPropertyAttribute标记需要的属性,不是所有的属性
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Controllers; using Microsoft.Extensions.DependencyInjection; using System.Collections.Generic; using System.Linq; using WebAppTest.CustomAttrributes; namespace WebAppTest.Extensions { /// <summary> /// 自定义的控制器创建对象,以便使用ioc创建控制器,其实IOC就是一个字典Dictionary /// </summary> public class CustomServiceBaseControllerActivator : IControllerActivator { public object Create(ControllerContext context) { var controllerType = context.ActionDescriptor.ControllerTypeInfo.AsType(); //IOC容器完成实例化 var controllerInstance = context.HttpContext.RequestServices.GetRequiredService(controllerType); //Controller控制器属性注入,CustomPropertyAttribute标记需要的属性,不是所有的属性 foreach (var prop in controllerType.GetProperties().Where(prop => prop.IsDefined(typeof(CustomPropertyAttribute), true))) { var propValue = context.HttpContext.RequestServices.GetRequiredService(prop.PropertyType); prop.SetValue(controllerInstance, propValue); } //Controller控制器方法注入,CustomMethodAttribute标记需要的方法,不是所有的方法 foreach (var method in controllerType.GetMethods().Where(method => method.IsDefined(typeof(CustomMethodAttribute), true))) { var methodParameters = method.GetParameters(); List<object> listMethodParameters = new List<object>(); foreach (var para in methodParameters) { var paraValue = context.HttpContext.RequestServices.GetRequiredService(para.ParameterType); listMethodParameters.Add(paraValue); } //调用Controller控制器方法 method.Invoke(controllerInstance, listMethodParameters.ToArray()); } return controllerInstance; } public void Release(ControllerContext context, object controller) { //throw new NotImplementedException(); } } }
3、控制器Controller中属性注入和方法注入
using Microsoft.AspNetCore.Mvc; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using WebAppTest.CustomAttrributes; using WebAppTest.Extensions; using WebAppTest.Services; namespace WebAppTest.Controllers { public class TestController : Controller { /// <summary> /// 属性注入--Controller控制器属性注入,CustomPropertyAttribute标记需要的属性,不是所有的属性 /// </summary> [CustomPropertyAttribute] public ITestA _testA { get; set; } /// <summary> /// 用于方法注入的字段 /// </summary> private ITestB _testB; /// <summary> /// 方法注入--Controller控制器方法注入,CustomMethodAttribute标记需要的方法,不是所有的方法 /// </summary> [CustomMethodAttribute] public void CreateInstance(ITestB testB) { _testB = testB; } public IActionResult Index() { _testA.Show(); _testB.Show(); //((ITestA)_testA.AOP(typeof(ITestA))).Show(); return View(); } } }
4. Startup中添加
//把控制器作为服务注册,然后使用它内置的ioc来替换原来的控制器的创建器,这样就可以使用IOC来依赖注入和控制反转创建对应的控制器 services.AddControllersWithViews().AddControllersAsServices(); services.Replace(ServiceDescriptor.Transient<IControllerActivator, CustomServiceBaseControllerActivator>()); services.AddTransient<ITestA, TestA>(); services.AddTransient<ITestB, TestB>();
龙腾一族至尊龙骑