【问题标题】:Castle Dynamic Proxy MixinInstance behaviourCastle 动态代理 MixinInstance 行为
【发布时间】:2020-05-03 21:08:38
【问题描述】:

我在我的 POCO 类中使用 Castle 的 DynamicProxy 生成器与非虚拟成员作斗争,并想出一种方法来使用以下代码使用 ProxyGenerationOptions.AddMixinInstance() 实现这一点。

我的问题是,如果 mixin 可以将非虚拟成员发送到拦截器,那么基于我的实际类型时,标准代理不能吗???

下面是代码。

void Main()
{
    var generator = new ProxyGenerator();

    Console.WriteLine(Environment.NewLine + "============ Proxy - With Target ===============");
    var person = new Person { Name = "Freddy FudPucker", Age = 62 };
    var personProxy = CreateProxyWithTarget(generator, person);


    Console.WriteLine(((IPerson)personProxy).Name);
    Console.WriteLine(((IPerson)personProxy).Age);
    ((IPerson)personProxy).Name = "Speedy";
    ((IPerson)personProxy).Age = 64;
    Console.WriteLine(((IPerson)personProxy).Name);
    Console.WriteLine(((IPerson)personProxy).Age);

    Console.WriteLine(((ITracking)personProxy).State);
    ((ITracking)personProxy).State = 1;
    Console.WriteLine(((ITracking)personProxy).State);
}

public object CreateProxyWithTarget(ProxyGenerator generator, Person person)
{
    var options = new ProxyGenerationOptions();
    options.AddMixinInstance(person);
    options.AddMixinInstance(new Tracking());
    return generator.CreateClassProxyWithTarget(typeof(ProxyBase), new[] { typeof(ITracking) }, new ProxyBase(), options, new PersonInterceptor());
}

给出以下输出

Person System.String get_Name()
Freddy FudPucker
62
Person Void set_Name(System.String)
Person Void set_Age(Int32)
Person System.String get_Name()
Speedy
Person Int32 get_Age()
64
Person Int32 get_State()
0
Person Void set_State(Int32)
Person Int32 get_State()
1

下面是支持的类和接口

public class ProxyBase
{
    public ProxyBase()
    {

    }
}

public interface ITracking
{
    int State { get; set; }
}

public class Tracking : ITracking
{
    public int State { get; set; }
}


public class Person : IPerson
{
    public string Name { get; set; }

    public int Age { get; set; }
}

public interface IPerson
{
    string Name { get; set; }
    int Age { get; set; }
}

public interface IPersonAge
{
    int Age { get; set; }
}

class PersonInterceptor : IInterceptor
{
    public void Intercept(IInvocation invocation)
    {
        Console.WriteLine($"Person {invocation.Method}");
        invocation.Proceed();
    }
}

【问题讨论】:

    标签: castle-dynamicproxy


    【解决方案1】:

    您的具有目标的类代理继承自您的 ProxyBase 类,因此需要虚拟成员,而 DynamicProxy 混合在该代理类上实现混合类接口的成员,因此是隐式虚拟的。有效的 mixins 就像带有目标的接口代理一样工作。

    // You can do this (from your example):
    Console.WriteLine(((IPerson)personProxy).Name);
    
    // ... but not this (because the proxy isn't a Person but is an IPerson):
    Console.WriteLine(((Person)personProxy).Name);
    

    AddMixinInstance 的 XML 文档有更多详细信息:https://github.com/castleproject/Core/blob/e2dfb57020d9dbb4b31f3ce548b34cb35ffa3307/src/Castle.Core/DynamicProxy/ProxyGenerationOptions.cs#L208-L225

    【讨论】:

      猜你喜欢
      • 2013-03-06
      • 2011-01-20
      • 2019-02-15
      • 2013-02-11
      • 2011-04-03
      • 2012-06-26
      • 2010-12-06
      • 1970-01-01
      • 2015-11-05
      相关资源
      最近更新 更多