Ninject 通过城堡动态代理拦截具有非空构造函数的代理类

2024-04-17

我当前的大部分实现都基于此处提供的信息:

Ninject 拦截任何具有特定属性的方法吗? https://stackoverflow.com/questions/6386461/ninject-intercept-any-method-with-certain-attribute

我使用自定义规划策略类,它查找具有给定属性(不是 ninject 拦截器属性)的所有方法,如果符合条件,则将被代理。

用法示例如下:

Kernel.Components.Add<IPlanningStrategy, CustomPlanningStrategy<LoggingAttribute, LoggerInterceptor>>();

然后,这将寻找任何具有[Logging]属性,然后将使用日志记录拦截器。

但是,当动态代理尝试代理具有相关属性的方法时,我目前从动态代理中收到 InvalidProxyConstructorArgumentsException 。现在我记得读过您需要虚拟方法,但是我不记得看到您必须有一个无参数构造函数。

所有绑定都是针对接口完成的,AOP 拦截器通过属性和上面链接中提到的自定义代理规划类发生。

那么有没有办法获得动态代理(或linfu版本)来代理具有依赖关系的构造函数的类? (所有依赖项都在内核中,因此并非无法解决)。


查看代理生成代码:https://github.com/ninject/ninject.extensions.interception/blob/master/src/Ninject.Extensions.Interception.DynamicProxy/DynamicProxyProxyFactory.cs https://github.com/ninject/ninject.extensions.interception/blob/master/src/Ninject.Extensions.Interception.DynamicProxy/DynamicProxyProxyFactory.cs

    if (targetType.IsInterface)
        {
            reference.Instance = this.generator.CreateInterfaceProxyWithoutTarget(targetType, additionalInterfaces, InterfaceProxyOptions, wrapper);
        }
        else
        {
            object[] parameters = context.Parameters.OfType<ConstructorArgument>()
                .Select(parameter => parameter.GetValue(context, null))
                .ToArray();
            reference.Instance = this.generator.CreateClassProxy(targetType, additionalInterfaces, ProxyOptions, parameters, wrapper);
        }

可以看到ninject的动态代理扩展只是传递ConstructorArgument发送到 Castle 动态代理生成器。

因此,无需更改 ninject 扩展或创建自己的扩展,您需要将所有依赖项作为构造函数参数传递。您还可以尝试属性/方法注入是否有效(请参阅https://github.com/ninject/ninject/wiki/Injection-Patterns https://github.com/ninject/ninject/wiki/Injection-Patterns).

如果您控制代码,您可以向代理类添加接口,然后使用“与目标的接口代理 http://docs.castleproject.org/Tools.Kinds-of-proxy-objects.ashx“。这允许将代理实例化与目标(代理类)实例化分离——>目标可以注入依赖项ctor,而无需对ninject(-扩展)进行任何更改。

澄清: 具有应代理的以下类:

public interface IBar { }

public class Foo 
{
     public Foo(IBar bar)
     {
     }
}

以及以下绑定:

Bind<Foo>().ToSelf().Intercept().With<SomeInterceptor>();
Bind<IBar>().To<Bar>();

然后检索一个Foo从 ninject 容器中:

IResolutionRoot.Get<Foo>();

行不通的。

将所有构造函数参数放在 ninject 上下文中以使其正常工作

但是,我们可以改变检索Foo使其发挥作用:

var bar = IResolutionRoot.Get<IBar>();
IResolutionRoot.Get<Foo>(new ConstructorArgument("bar", bar);

现在这是次优的,因为 ninject 不会自动执行依赖项解析。

向代理类添加接口以使其更好地工作

我们可以通过使用“带有目标的接口代理”来解决这个问题。 首先,我们向代理类添加一个接口:

public interface IFoo{ }

public class Foo : IFoo
{
     public Foo(IBar bar)
     {
     }
}

然后我们将绑定更改为:

Bind<IFoo>().To<Foo>().Intercept().With<SomeInterceptor>();

然后检索一个Foo从 ninject 容器中:

IResolutionRoot.Get<Foo>();

works.

另一个可能更简单(&丑陋?)的解决方案根据@Daniel 的说法,这是有效的: 添加两个构造函数到代理类型:

  • one protected不带参数的构造函数。这个是DynamicProxy创建代理的。
  • one public/internal带有参数的构造函数,由 ninject 用来实例化代理类型。

Ninject 将自动选择具有最多可解析参数的构造函数。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Ninject 通过城堡动态代理拦截具有非空构造函数的代理类 的相关文章

  • 将 Stream 反序列化为 List 或任何其他类型

    尝试将流反序列化为List
  • 键盘加速器在 UWP 应用中停止工作

    我正在尝试将键盘加速器添加到 UWP 应用程序中的 CommandBar 菜单项 当应用程序启动时 这工作正常 但在我第一次打开溢出菜单后 加速器停止工作 这似乎不会发生在主要命令 菜单之外 上 只有溢出菜单内的辅助命令才会发生 此外 单击
  • 在Application_AquireRequestState事件中用POST数据重写Url

    我有一个在其中注册路线的代码Application AcquireRequestState应用程序的事件 注册路由后 我会在 Http 运行时缓存中设置一个标志 这样我就不会再次执行路由注册代码 在此事件中注册路线有特定原因Applicat
  • 访问“if”语句之外的变量

    我怎样才能使insuranceCost以外可用if陈述 if this comboBox5 Text Third Party Fire and Theft double insuranceCost 1 在 if 语句之外定义它 double
  • Qt 计算和比较密码哈希

    目前正在 Qt 中为测验程序构建面向 Web 的身份验证服务 据我了解 在数据库中存储用户密码时 必须对其进行隐藏 以防落入坏人之手 流行的方法似乎是添加的过程Salt https en wikipedia org wiki Salt cr
  • 矩阵向量变换

    我正在编写一个代码来制作软件蒙皮器 骨骼 皮肤动画 并且我正处于 优化 阶段 蒙皮器工作得很好 并且在 Core 上 1 09 毫秒内对 4900 个三角形网格与 22 个骨骼进行蒙皮Duo 2 Ghz 笔记本 我需要知道的是 1 有人可以
  • 有没有办法使用 i387 fsqrt 指令获得正确的舍入?

    有没有办法使用 i387 fsqrt 指令获得正确的舍入 除了改变精确模式在 x87 控制字中 我知道这是可能的 但这不是一个合理的解决方案 因为它存在令人讨厌的重入型问题 如果 sqrt 操作中断 精度模式将出错 我正在处理的问题如下 x
  • 方法“xxx”不能是事件的方法,因为该类派生的类已经定义了该方法

    我有一个代码 public class Layout UserControl protected void DisplayX DisplayClicked object sender DisplayEventArgs e CurrentDi
  • 如何使用 wpf webbrowser 将数据发布到 Web 服务器

    我想从数据库获取数据并使用它来让用户登录到网站 我有一个包含 Web 浏览器控件的 wpf 页面 我有这样的代码 用于将用户登录到用 php 编写的网站
  • 防止GDB中的PLT(过程链接表)断点

    在最新版本的 GDB 中 在库函数调用上设置断点会导致多个实际断点 调用过程链接表 PLT 实际的函数调用 这意味着当调用库函数时 我们每次都会经历两次中断 在以前的 GDB 版本中 只会创建 2 因此您只能得到一次中断 那么问题来了 是否
  • dropdownlist DataTextField 由属性组成?

    有没有一种方法可以通过 C 使 asp net 中的下拉列表的 datatextfield 属性由对象的多个属性组成 public class MyObject public int Id get set public string Nam
  • 如何用 C 语言练习 Unix 编程?

    经过五年的专业 Java 以及较小程度上的 Python 编程并慢慢感觉到我的计算机科学教育逐渐消失 我决定要拓宽我的视野 对世界的一般用处 并做一些 对我来说 感觉更重要的事情就像我真的对机器有影响一样 我选择学习 C 和 Unix 编程
  • 从事务范围调用 WCF 服务方法

    我有这样的代码 using TransactionScope scope TransactionScopeFactory CreateTransactionScope some methodes calls for which scope
  • 使用(linq to sql)更新错误

    我有两个表 通过外键 CarrierID 绑定 Carrier CarrierID CarrierName CarrierID 1 CarrierName DHL CarrierID 2 CarrierName Fedex Vendor V
  • TPL 数据流块下游如何获取源生成的数据?

    我正在使用 TPL Dataflow 处理图像 我收到处理请求 从流中读取图像 应用多次转换 然后将生成的图像写入另一个流 Request gt Stream gt Image gt Image gt Stream 为此 我使用块 Buff
  • 如何将对象转换为传递给函数的类型?

    这不会编译 但我想做的只是将对象转换为传递给函数的 t public void My Func Object input Type t t object ab TypeDescriptor GetConverter t ConvertFro
  • 从有符号字符转换为无符号字符然后再转换回来?

    我正在使用 JNI 并有一个 jbyte 类型的数组 其中 jbyte 表示为有符号字符 即范围从 128 到 127 jbyte 表示图像像素 对于图像处理 我们通常希望像素分量的范围为0到255 因此 我想将jbyte值转换为0到255
  • g++ C++0x 枚举类编译器警告

    我一直在将可怕的 C 类型安全伪枚举重构为新的 C 0x 类型安全枚举 因为它们是way更具可读性 不管怎样 我在导出的类中使用它们 所以我明确地将它们标记为导出 enum class attribute visibility defaul
  • 无法使 Polly 超时策略覆盖 HttpClient 默认超时

    我正在使用 Polly 重试策略 并且正如预期的那样 在重试过程中HttpClient达到 100 秒超时 我尝试了几种不同的方法来合并 Polly 超时策略 将超时移至每次重试而不是总计 但 100 秒超时仍然会触发 我读过大约 5 个
  • FindAsync 很慢,但是延迟加载很快

    在我的代码中 我曾经使用加载相关实体await FindAsync 希望我能更好地遵守 C 异步指南 var activeTemplate await exec DbContext FormTemplates FindAsync exec

随机推荐

  • Julia 似乎没有使用字符串来执行插值

    官方文档指出 连接和字符串插值调用string 将对象转换为字符串形式 然而 以下最小工作示例似乎证明了其他情况 type MyType x Int end import Base string Base string m MyType w
  • ... 不支持谷歌地图 Javascript API。使用其他浏览器

    我正在使用两个不同的第三方程序 不同的公司 它们显然使用 Google Maps Javascript API 当他们加载地图时 会显示世界地图 但会显示一条错误消息 Der von Ihnen verwendete Browser wir
  • 如何用动画消除一堆模态视图控制器而不在屏幕上闪烁顶部和底部之间任何呈现的 VC?

    更新 通过下面的 屏幕截图 方法修复 这可行 但是有更优雅的方法吗 我将如何消除一堆带有动画的模态视图控制器 而不在屏幕上闪烁顶部和底部之间任何呈现的 VC 尝试用动画来做到这一点是行不通的 请参阅下面的代码和描述我的问题的内嵌注释 您可以
  • 当客户端不正常退出时,如何检测服务器上 Python aiohttp Web 套接字的关闭

    我有一个简单的命令和控制服务器server py 完全不安全 不要使用 被动客户端update client py和另一个可以发送命令的客户端update commander py 有一个 http 端点http 0 0 0 0 8080
  • NAT 穿越和 IPv6

    我很好奇一旦 IPv6 的部署和使用增加 NAT 和 NAT 穿越机制的用处 我们有很多 NAT 遍历机制 包括专有的 主要用于某种住宅或企业 NAT 背后的 IPv4 设备 客户端 鉴于 NAT 的出现是因为 IPv4 缺乏可用地址 那么
  • 未找到 CSS 和 JS 的 Vue dist 路径

    我在构建后渲染 VueJS 应用程序时遇到问题 当我查看构建文件夹并检查路径时 我的资产 css 和 javascript 的路径开头有一个正斜杠 这使得我的 css 资源和 javascript 无法找到 我想知道在运行构建脚本之前如何避
  • 尝试将 CABasicAnimation 位置和图层不透明度延迟 3 秒,但是

    我试图使用 setBeginTime 将图层的不透明度和位置的动画延迟 3 秒 我将图层命名为boxLayer 动画进展顺利 但在前 3 秒内 该图层不应显示 该图层以其最终位置和不透明度显示 不应该 组动画并不能解决该问题 有人可以帮忙吗
  • C++2a 合约编程和编译器

    我有兴趣研究最近接受的C 20 的合约编程 https en cppreference com w cpp language attributes contract用于学习和调查目的 当我四处寻找编译器支持时 我很失望没有找到任何支持 两个
  • Laravel dusk 不工作 .env.dusk.local

    我有一个应用程序 我想使用 Laravel Dusk 我创建了一个名为 env dusk local带有用于测试的数据库和名为的文件 env使用我的默认数据库 我运行 php artisan 命令并创建了一个用户 register 在我使用
  • golang 中有惯用的范围语义吗?

    我想知道是否有任何惯用的方式来表示scoped语义 我所说的范围是指 范围互斥体 一个衬垫而不是显式锁定 延迟解锁 记录函数 或任何代码块 的入口和出口 测量执行时间 前两个项目符号的示例代码 package main import log
  • 从 DynamoDb 查询的 Python 脚本未提供所有项目

    我编写了以下 python 代码来从表中获取数据 但它没有按照我想要的方式获取所有项目 当我检查 DynamoDb 的 AWS 控制台页面时 我可以看到比从脚本中获得的条目多得多的条目 from future import print fu
  • 两个本体之间的映射

    我如何使用 owl sameas 来链接两个本体 如果我有本体A c rdf type owl Class 和本体B d rdf type owl Class 我想将两个本体与共享概念 c 和 d 联系起来 我读过有关 owl sameas
  • Flutter:webview_flutter 更新同一 webview 小部件中的 url

    嘿 我正在尝试创建一个屏幕 显示带有底部应用栏的网络视图 因此 您加载网络视图 当点击底部应用栏中的某个项目时 其他网站应该加载到同一个网络视图中 除了我最初解析的网站之外 我不知道如何打开另一个网站 我尝试使用 setState 更新网址
  • 处理kendo调度程序中的销毁事件

    我正在使用剑道调度程序 调度程序网格中添加了事件 当鼠标悬停在每个事件上时 右上角会出现一个小 x 即该事件的销毁事件 单击该事件时会显示一条警告消息 您确定要删除此事件吗 如果单击 是 它将继续并删除该事件 这是我的要求 正如您在上面看到
  • WSO2 身份服务器 - Oauth 2.0 - Java 签核示例

    我为 Oauth2 身份验证流程编写了一个基于 Java 的签核例程 令牌撤销 请参阅下面的代码实现 遵循手册中描述的 cURL 协议说明 here https docs wso2 com display IS500 OAuth Token
  • 下划线模板 - 更改标记标记

    开箱即用的下划线模板使用标记对于原始的 和用于 HTML 转义内容 我知道您可以使用以下方法更改标记 templateSettings interpolate g 但这与原始内容和转义内容有何关系 在我看来 你最终只能得到一种类型的标记 或
  • ScalaCheck 生成 BST

    我正在尝试使用 ScalaCheck 创建 BST 的 Gen 但是当我调用 sample 方法时 它给出了 java lang NullPointerException 我哪里错了 sealed trait Tree case class
  • 如何从

    我有一个严重的问题 我想从标签中提取内容 例如 div class main content div class sub content Sub content here div Main content here div 我期望的输出是
  • 机器人按键在 Linux 中不工作

    我多次使用 Robot 类 但在 Windows 中没有遇到任何问题 但这次我使用的是 Fedora 如果我尝试一下 keyPress KeyEvent VK WINDOWS 它不工作 如何在linux Fedora 中模拟按Windows
  • Ninject 通过城堡动态代理拦截具有非空构造函数的代理类

    我当前的大部分实现都基于此处提供的信息 Ninject 拦截任何具有特定属性的方法吗 https stackoverflow com questions 6386461 ninject intercept any method with c