Castle Dynami c Proxy MixinInstance поведение - PullRequest
0 голосов
/ 17 января 2020

Я боролся с не виртуальными членами в своих классах POCO, используя генератор CastleicProxy Касла, и нашел способ добиться этого, используя ProxyGenerationOptions.AddMixinInstance(), используя приведенный ниже код.

У меня есть вопрос Вот почему, если миксин может отправлять не виртуальные элементы перехватчику, не может ли стандартный прокси-сервер, основанный на моем фактическом типе ???

Ниже приведен код.

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();
    }
}

1 Ответ

0 голосов
/ 19 января 2020

Ваш прокси класса с target наследует от вашего класса ProxyBase, поэтому требуются виртуальные члены, в то время как миксины DynamicProxy реализуют члены интерфейсов класса mixin в этом прокси-классе, поэтому неявно являются виртуальными. Эффективно миксины работают как интерфейсные прокси с целевыми объектами.

// 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);

Документация XML для AddMixinInstance содержит некоторые подробности: https://github.com/castleproject/Core/blob/e2dfb57020d9dbb4b31f3ce548b34cb35ffa3307/src/Castle.Core/DynamicProxy/ProxyGenerationOptions.cs#L208 -L225

...