陪你听风

Net Core使用依赖注入应用过滤器+自定义中间件

电脑版发表于:2019/12/24 16:16

圣诞节快乐

过什么圣诞节哦,圣诞老人已经被我抓起来了。

 


  

我们今天主要讲的是NET Core中的依赖注入数据,使用过滤器调用+自定义中间件

第一步:我们可以在项目里新建一个文件夹:Filter,然后添加一个过滤器的类,实现接口。

  //net core过滤器中使用依赖注入
    public class LogFilter : IActionFilter
    {
        public void OnActionExecuted(ActionExecutedContext context)
        {
           
        }
        public void OnActionExecuting(ActionExecutingContext context)
        {
            
        }
    }

第二步:在Startup.cs服务里的ConfigureServices方法为过滤器添加全局的方法。

   //为net core 过滤器添加全局变量
   services.AddMvc(a => a.Filters.Add(new LogFilter())).SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

然后我们调试就可以看到,项目先进过滤器,再进的home/index控制器。

第三步:我们为了做一些控制器里操作,肯定需要数据,这里调用数据也有些不同。

我们要使用依赖注入的数据,不能像以前一样实例化调用,需要定义一个接口对象,在调用对象。

 //得到对象
  private readonly IUserDAL _userDAL;
        public LogFilter(IUserDAL userDAL)
        {
            _userDAL = userDAL;
        }
        public void OnActionExecuted(ActionExecutedContext context)
        {
           
        }
 public void OnActionExecuting(ActionExecutingContext context)
        {
            
        }


然后我们要在Startup.cs服务里的ConfigureServices方法为过滤器AddMvc()添加全局的方法,注释原来的。

  //过滤器配置依赖注入的关系
   services.AddScoped<LogFilter>();
   
 //为net core 过滤器添加全局变量,依赖注入数据,需要配置依赖注入的关系
  services.AddMvc(a => a.Filters.AddService<LogFilter>()).SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

下面我们运行调试项目,也是先进入过滤器作判断的,并且过滤器里的数据也是拿到的,大家做的时候可以仔细看下。

控制器home/index的代码如下:

   private readonly IUserDAL _userDAL;
   public HomeController(IUserDAL userDAL)
        {
            _userDAL = userDAL;         
        }
        
  public IActionResult Index()
        {
            int hashcode = _userDAL.GetHashCode();
            ViewBag.hashcode = hashcode;
            //  Response.Body.Write(System.Text.Encoding.Default.GetBytes(hashcode + ""));
            //直接在容器里边获取依赖注入
            IUserDAL userDALTwo = HttpContext.RequestServices.GetService(typeof(IUserDAL)) as IUserDAL;
            ViewBag.hashcode2 = userDALTwo.GetHashCode();
            return View();
        }

前台用ViewBag传值就行了,输出值如下:

 不知道大家有没有注意,我们在Startup.cs服务里为过滤器添加依赖关系的时候,用的模式是AddScoped()

 实际上这里还有一个知识点。就是  -->


Asp.NetCore 服务依赖注入的三个模式以及三个模式的区别


AddTransient瞬时模式:每次请求,都获取一个新的实例。即使同一个请求获取多次也会是不同的实例

使用方式:services.AddTransient<IOperationTransient, Operation>();


AddScoped:每次请求,都获取一个新的实例。同一个请求获取多次会得到相同的实例

使用方式:services.AddScoped<IMyDependency, MyDependency>();

 

AddSingleton单例模式:每次都获取同一个实例

使用方式:services.AddSingleton<IOperationSingleton, Operation>();


以我们项目的UserDAL,UserDALTwo,IUserDAL为例。调用数据

   //服务添加用户继承的接口:配置依赖注入的关系
    services.AddTransient<IUserDAL, UserDAL>();  //瞬时模式

     //  services.AddSingleton<IUserDAL, UserDALTwo>();  //单例模式  因为UserDAL里面的注入和单例模式有冲突,不可用

      //services.AddScoped<IUserDAL, UserDALTwo>(); //同一次请求:区别于瞬时模式和单利模式 UserDAL和UserDALTwo都可以使用

       我们使用瞬时模式时,调用数据,运行效果如下:

    

   我们可以发现hashcode和hashcode2,每次刷新的值是不相同的。单例模式的话就是每次都获取同一个实例,这里就不演示了。


   最后的一个重点就是Net Core 的自定义中间件

一、中间件介绍

        中间件是组装到应用程序管道中用来理请求逻辑和响应逻辑的组件。

  每个组件都可以:

    1.选择是否将请求传递给管道中的下一个组件。

    2.调用管道中的下一个组件之前和之后执行的工作。

  请求委托(Requestdelegates)用于构建请求管道,处理每个HTTP请求。

 二、自定义中间件

有很多中间件微软已经给我提供了,但是如何自定义中间件呢?

第一步:新建一个文件夹,定义一个类,并添加以下代码

 public class RequestIPMiddleware
    {
        private readonly RequestDelegate _next;
        //写系统控制台日志
        private readonly ILogger _logger;
        // 管道执行到该中间件时候下一个中间件的RequestDelegate请求委托,如果有其它参数,也同样通过注入的方式获得
        public RequestIPMiddleware(RequestDelegate next, ILoggerFactory logger)
        {
               //通过注入方式获得对象
            _next = next;
            _logger = logger.CreateLogger<RequestIPMiddleware>();
        }
       //自定义中间件要执行的逻辑
        public async Task Invoke(HttpContext content)
        { 
        Console.WriteLine("Request1");//请求进来时逻辑,为了验证顺序性,打印一句话
              await _next(content);//把context传进去执行下一个中间件
              await content.Response.WriteAsync("<p>Response1</p>");//响应出去时逻辑,为了验证顺序性,输出一句话
        } 
    }

  第二步:在Startup类中的Configure方法下,通过调用UseMiddleware方法注册中间件。
            如果自定义的中间件Invoke方法需要传递参数,则可以通过UseMiddleware方法把参数传进去,
            而自定义的RequestIPMiddleware则需要通过依赖注入的方式拿到所传进去的参数


    //使用自己的中间件
   app.UseMiddleware<RequestIPMiddleware>();
以项目调试,(不要以IIS调试),我们就能看到效果,
 
 

在自定义中间件的系统控制台文件中还有一些提示效果。
 
  public async Task Invoke(HttpContext content)
        {
            //Console.WriteLine("Request1");//请求进来时逻辑,为了验证顺序性,打印一句话
            //await _next(content);//把context传进去执行下一个中间件
            //await content.Response.WriteAsync("<p>Response1</p>");//响应出去时逻辑,为了验证顺序性,输出一句话
            //执行操作  LogInformation:详情信息
            //LogError:错误信息  ,LogWarning:警告信息
            _logger.LogWarning("执行自己的中间件,获取Ip地址");
            _logger.LogError("My Ip:" + content.Connection.RemoteIpAddress.ToString());
            //执行下一个中间件
            await _next.Invoke(content);
        }
  效果如下:

 


  最后一个知识点就是用扩展方法和链式编程,封装自己的中间件

  同样也是在该文件夹下新建一个类:
   
 public static class RequestIPMwExtensions
    {
        //用扩展方法和链式编程,封装自己的中间件
        //扩展方法的标识:static ,this
        public static IApplicationBuilder UseRequestIP(this IApplicationBuilder app)
        {
            //链式编程:(返回一个自己对象)
            return app.UseMiddleware<RequestIPMiddleware>();
        }
        //中间件和过滤器的区别:
        //1,过滤器还是中间件里面的一个小模块
        //2,配置方式不同
        //3,过滤器更贴近业务
        //4,中间件更早
    }
  最后在Startup.cs服务里的Configure方法调用即可。
 
 //使用自己扩展方法的中间件
   app.UseRequestIP();

好啦,本次文章分享就到这里了,喜欢的朋友可以加收藏哦。


关于TNBLOG
TNBLOG,技术分享。技术交流:群号677373950
ICP备案 :渝ICP备18016597号-1
App store Android
精彩评论
{{item.replyName}}
{{item.content}}
{{item.time}}
{{subpj.replyName}}
@{{subpj.beReplyName}}{{subpj.content}}
{{subpj.time}}
猜你喜欢