C# unity 通过属性拦截

2023-11-24

有没有办法在 C# unity 中使用属性拦截并将对象注册代码保留在 XML 文件(如 app.config)中?如果是的话,您能给我提供代码吗?这样的注册应该是什么样子?我做了很多解决方法,但没有找到解决此问题的有效解决方案。


我假设您的意思是使用自定义属性来指示要拦截的方法。您可以使用策略注入来通过XML配置来实现拦截。

首先,我们定义一个自定义属性:

[AttributeUsage(AttributeTargets.Method)]
public class MyInterceptionAttribute : Attribute
{
}

接下来我们可以创建一个ICallHandler来做一些拦截工作。此实现将仅在方法之前和之后执行 Console.WriteLine:

public class MyLoggingCallHandler : ICallHandler
{
    IMethodReturn ICallHandler.Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
    {
        Console.WriteLine("Invoking " + input.MethodBase.Name);
        IMethodReturn result = getNext()(input, getNext);
        Console.WriteLine("Done Invoke");
        return result;
    }

    int ICallHandler.Order { get; set; }
}

接下来假设我们有一些接口和实现:

public interface IMyClass
{
    void Do();
    void DoAgain();
}

public class MyClass : IMyClass 
{
    [MyInterception]
    public void Do()
    {
        Console.WriteLine("Do!");
    }

    public void DoAgain()
    {
        Console.WriteLine("Do Again!");
    }
}

请注意,我已将自定义属性 MyInterception 仅应用于 Do 方法,而不应用于 DoAgain 方法。我们将拦截对 Do 方法的所有调用。

接下来,我们创建配置来定义策略,配置匹配规则并注册类型和拦截器:

<?xml version="1.0"?>
<configuration>
  <configSections>
    <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration"/>
  </configSections>
  <unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
    <namespace name="UnityCallHandlerConfig" />
    <assembly name="UnityCallHandlerConfig"  />
    <sectionExtension type="Microsoft.Practices.Unity.InterceptionExtension.Configuration.InterceptionConfigurationExtension, Microsoft.Practices.Unity.Interception.Configuration"/>
    <container>
      <extension type="Interception"/>
      <interception>
        <policy name="Policy">
          <matchingRule name="Match" type="Microsoft.Practices.Unity.InterceptionExtension.CustomAttributeMatchingRule, Microsoft.Practices.Unity.Interception">
            <constructor>
              <param name="attributeType" value="UnityCallHandlerConfig.MyInterceptionAttribute, UnityCallHandlerConfig" typeConverter="AssemblyQualifiedTypeNameConverter" />
              <param name="inherited">
                <value value="false"/>
              </param>
            </constructor>
          </matchingRule>
          <callHandler name="MyLogging" type="MyLoggingCallHandler">
            <lifetime type="singleton"/>
          </callHandler>
        </policy>
      </interception>
      <register type="IMyClass" mapTo="MyClass">
        <interceptor type="InterfaceInterceptor"/>
        <interceptionBehavior type="PolicyInjectionBehavior"/>
      </register>
    </container>
  </unity>

  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/>
  </startup>
</configuration>

我们还需要一个类型转换器将自定义属性的字符串表示形式转换为正确的类型:

public class AssemblyQualifiedTypeNameConverter : ConfigurationConverterBase
{
    public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)
    {
        if (value != null)
        {
            Type typeValue = value as Type;
            if (typeValue == null)
            {
                throw new ArgumentException("Cannot convert type", typeof(Type).Name);
            }

            if (typeValue != null) return (typeValue).AssemblyQualifiedName;
        }
        return null;
    }

    public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
    {
        string stringValue = (string)value;
        if (!string.IsNullOrEmpty(stringValue))
        {
            Type result = Type.GetType(stringValue, false);
            if (result == null)
            {
                throw new ArgumentException("Invalid type", "value");
            }

            return result;
        }
        return null;
    }
}

一旦我们完成所有设置,我们就可以创建一个容器并加载配置:

var container = new UnityContainer().LoadConfiguration();

var myClass = container.Resolve<IMyClass>();
myClass.Do();
myClass.DoAgain();

输出将是:

Invoking Do
Do!
Done Invoke
Do Again!

显示第一个方法被拦截,而第二个方法没有被拦截。

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

C# unity 通过属性拦截 的相关文章

  • 在 VS2017 下使用 Conan 和 CMake 项目进行依赖管理

    我正在尝试使用 CMake 与 VS2017 集成为 C 设置一个开发环境 以便在 Linux x64 下进行编译 为了更好地管理依赖关系 我选择使用 Conan 但我对这个软件还很陌生 我想知道让 VS2017 识别项目依赖关系的最佳方法
  • 分段错误(核心转储)错误

    我的程序编译罚款 但在输入文件时出现 分段错误 核心转储 错误 我没有正确处理 ostream 吗 include
  • 内联函数/方法

    声明 内联函数必须在调用之前定义 这个说法正确吗 EDIT 该问题最初是德语 内联功能穆森 弗 伊赫雷姆 奥夫鲁夫定义 sein 也许它对任何人都有帮助 是的 它是正确的 但只是部分正确 它可能正确地重新构建如下 内联函数必须在每个翻译单位
  • 将字节数组转换为托管结构

    更新 这个问题的答案帮助我编写了开源项目GitHub 上的 AlicanC 现代战争 2 工具 https github com AlicanC AlicanC s Modern Warfare 2 Tool 你可以看到我是如何阅读这些数据
  • ASP.NET Core 与现有的 IoC 容器和环境?

    我想运行ASP NET 核心网络堆栈以及MVC在已托管现有应用程序的 Windows 服务环境中 以便为其提供前端 该应用程序使用 Autofac 来处理 DI 问题 这很好 因为它已经有一个扩展Microsoft Extensions D
  • SSL/TLS/HTTPS 站点在 C#/.NET WebBrowser 控件中非常慢,但在 Internet Explorer 中则很好

    背景 我正在修改自动维基浏览器 http en wikipedia org wiki Wikipedia AutoWikiBrowser使用托管在安全服务器上的 MediaWiki 站点 我允许用户通过 C 应用程序中的 WebBrowse
  • 如何尝试/捕获所有异常

    我正在完成由其他人启动的 UWP 应用程序 该应用程序经常崩溃 我总是陷入困境应用程序 at if global System Diagnostics Debugger IsAttached global System Diagnostic
  • 从 C 结构生成 C# 结构

    我有几十个 C 结构 我需要在 C 中使用它们 典型的 C 结构如下所示 typedef struct UM EVENT ULONG32 Id ULONG32 Orgin ULONG32 OperationType ULONG32 Size
  • mprotect 之后 malloc 导致分段错误

    在使用 mprotect 保护内存区域后第一次调用 malloc 时 我遇到分段错误 这是执行内存分配和保护的代码片段 define PAGESIZE 4096 void paalloc int size Allocates and ali
  • SFINAE 如何使用省略号?

    过去 当使用 SFINAE 选择构造函数重载时 我通常使用以下内容 template
  • 如何使用MySqlCommand和prepare语句进行多行插入?(#C)

    Mysql 给出了如何使用准备语句和 NET 插入行的示例 http dev mysql com doc refman 5 5 en connector net programming prepared html http dev mysq
  • libxml2 xmlChar * 到 std::wstring

    libxml2似乎将所有字符串存储在 UTF 8 中 如xmlChar xmlChar This is a basic byte in an UTF 8 encoded string It s unsigned allowing to pi
  • C++ 插件的“最适合”动态类型匹配

    我有一个几乎所有东西都是插件的架构 该架构以图形用户界面为基础 其中每个插件都由一个 表面 即用户可以通过其与插件交互的 UI 控件 表示 这些表面也是插件 每当添加新插件时 瘦主机都会自动确定哪个可用表面与其最匹配的 UI 如何在 C 中
  • C++11 动态线程池

    最近 我一直在尝试寻找一个用于线程并发任务的库 理想情况下 是一个在线程上调用函数的简单接口 任何时候都有 n 个线程 有些线程比其他线程完成得更快 并且到达的时间不同 首先我尝试了 Rx 它在 C 中非常棒 我还研究了 Blocks 和
  • 为什么要在 C++ 中使用 typedef?

    可以说我有 set
  • ASP.NET JQuery AJAX POST 返回数据,但在 401 响应内

    我的应用程序中有一个网页 需要调用我设置的 Web 服务来返回对象列表 这个调用是这样设置的 document ready function var response ajax type POST contentType applicati
  • 初始化 LPCTSTR /LPCWSTR [重复]

    这个问题在这里已经有答案了 我很难理解并使其正常工作 基本上归结为我无法成功初始化这种类型的变量 它需要有说的内容7 2E25DC9D 0 USB003 有人可以解释 展示这种类型的正确初始化和类似的值吗 我已查看此站点上的所有帮助 将项目
  • Visual Studio 2017 完全支持 C99 吗?

    Visual Studio 的最新版本改进了对 C99 的支持 最新版本VS2017现在支持所有C99吗 如果没有 C99 还缺少哪些功能 No https learn microsoft com en us cpp visual cpp
  • 服务器响应 PASV 命令返回的地址与建立 FTP 连接的地址不同

    System Net WebException 服务器响应 PASV 命令返回的地址与建立 FTP 连接的地址不同 在 System Net FtpWebRequest CheckError 在 System Net FtpWebReque
  • C#中为线程指定特殊的cpu

    我有 2 个线程 我想告诉其中一个在第一个 cpu 上运行 第二个在第二个 cpu 上运行 例如在具有两个 cpu 的机器中 我怎样才能做到这一点 这是我的代码 UCI UCIMain new UCI Thread UCIThread ne

随机推荐