【问题标题】:How to change a target using Castle DynamicProxy如何使用 Castle DynamicProxy 更改目标
【发布时间】:2013-08-01 06:09:13
【问题描述】:

我正在尝试了解 Castle 的 DynamicProxy,我想做的是在运行时更改生成的代理的目标。

这样的……

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Castle.DynamicProxy;

namespace ConsoleApplication16
{
    class Program
    {
        static void Main(string[] args)
        {
            IFoo foo = new Foo("Foo 1");

            IFoo foo2 = new Foo("Foo 2");

            foo.DoSomething("Hello!");

            ProxyGenerator generator = new ProxyGenerator();
            IFoo proxiedFoo = generator.CreateInterfaceProxyWithTarget<IFoo>(foo);

            proxiedFoo.DoSomething("Hello proxied!");

            (proxiedFoo as IChangeProxyTarget).ChangeProxyTarget(foo2); // cast results in null reference

            proxiedFoo.DoSomething("Hello!");
        }
    }
}

我认为生成的代理会实现IChangeProxyTarget,但转换为接口会导致空引用。

如何在运行时更改生成的代理的目标?

更新正如答案中提到的,我尝试使用CreateInterfaceProxyWithTargetInterface,但我仍然无法转换为 IChangeProxyTarget 来更改目标。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Castle.DynamicProxy;

namespace ConsoleApplication16
{
    class Program
    {
        static void Main(string[] args)
        {
            IFoo foo = new Foo("Foo 1");

            IFoo foo2 = new Foo("Foo 2");

            foo.DoSomething("Hello!");

            ProxyGenerator generator = new ProxyGenerator();
            IFoo proxiedFoo = generator.CreateInterfaceProxyWithTargetInterface<IFoo>(foo);

            proxiedFoo.DoSomething("Hello proxied!");

            IChangeProxyTarget changeProxyTarget = proxiedFoo as IChangeProxyTarget;

            if (changeProxyTarget == null) // always null...
            {
                Console.WriteLine("Failed");
                return;
            }

            changeProxyTarget.ChangeProxyTarget(foo2);

            proxiedFoo.DoSomething("Hello!");
        }
    }
}

【问题讨论】:

  • 那么你真正想解决什么问题?
  • 我的用例是我有一个通用服务主机缓存 WCF 回调通道。服务主机不知道它正在缓存什么类型的服务合同。我想为实际回调创建代理,以便在给定多线程环境的情况下控制回调通道的访问和生命周期。能够按需更换目标将使我能够做到这一点。我已经用我自己的从 RealProxy 派生的类做到了这一点。使用 RealProxy,您可以获得底层代理类并在其上调用方法,就像我对 Castle 所做的那样。
  • 对于投反对票的人,请解释我可以做些什么来改善这个问题。

标签: c# castle-dynamicproxy


【解决方案1】:

使用CreateInterfaceProxyWithTargetInterface

这将允许您更改代理/调用目标。

IChangeProxyTarget 也是通过调用类型实现的,而不是代理本身。

【讨论】:

  • 我试过了,代理仍然无法转换为 IChangeProxyTarget IChangeProxyTarget changeProxyTarget = proxiedFoo as IChangeProxyTarget; if (changeProxyTarget == null) // 总是 null... { Console.WriteLine("Failed");返回; }
  • 所以除了添加拦截器并通过调用对象进行更改之外,真的没有办法更改目标...
  • 代理的全部意义在于它是透明的。使用它的代码不知道它正在使用代理。因此它不会去尝试摆弄它。
  • 对,我希望其他使用基础服务主机的开发人员不知道我正在控制代理背后的 WCF 回调的生命周期和目标。但是,作为服务主机缓存回调,我的基础服务类确实希望能够摆弄它。我正在尝试创建一个透明的开发人员体验来控制缓存的 WCF 回调通道,这样开发人员就不必担心自己管理它,他们所要做的就是从缓存中获取一个回调通道(我想包装在代理中)。
  • 因为 DynamicProxy 显然不能做我想做的事,所以我将把它标记为“另外 IChangeProxyTarget 是通过调用类型实现的,而不是代理本身。 "
猜你喜欢
  • 1970-01-01
  • 2017-02-12
  • 2012-01-19
  • 1970-01-01
  • 2023-03-03
  • 2015-12-05
  • 1970-01-01
  • 1970-01-01
  • 2011-04-26
相关资源
最近更新 更多