zoukankan      html  css  js  c++  java
  • 使用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>(); 
  • 相关阅读:
    好文推荐 | 走近NLP学术界
    好文推荐 | 自然语言处理简介
    白嫖SSL证书部署(结合宝塔)
    基于本体体系的知识图谱构建
    Apache Jena Fuseki使用
    Springboot2.x入门——helloWorld
    Markdown语法
    freeswitch:error C2220: 警告被视为错误
    yate: windows下源码下载,配置,编译
    Android开源框架:volley
  • 原文地址:https://www.cnblogs.com/1175429393wljblog/p/14266783.html
Copyright © 2011-2022 走看看