Каков наилучший способ реализации динамического прокси в C #? - PullRequest
4 голосов
/ 04 января 2011

Мне нужно создать динамический прокси в C #. Я хочу, чтобы этот класс обернул другой класс и использовал его общедоступный интерфейс, перенаправляя вызовы для этих функций:

class MyRootClass
{
    public virtual void Foo()
    {
        Console.Out.WriteLine("Foo!");
    }

}

interface ISecondaryInterface
{
    void Bar();
}

class Wrapper<T> : ISecondaryInterface where T: MyRootClass
{
    public Wrapper(T otherObj)
    {
    }

    public void Bar()
    {
        Console.Out.WriteLine("Bar!");
    }
}

Вот как я хочу его использовать:

Wrapper<MyRootClass> wrappedObj = new Wrapper<MyRootClass>(new MyRootClass());
wrappedObj.Bar();
wrappedObj.Foo();

производить:

Bar!
Foo!

Есть идеи?

Какой самый простой способ сделать это?

Какой лучший способ сделать это?

Большое спасибо.

UPDATE

Я попытался следовать рекомендации Wernight и реализовать ее с помощью динамических прокси-серверов C # 4.0. К сожалению, я все еще застрял. Смысл прокси состоит в том, чтобы имитировать другой интерфейс, который (обычно, обычно) ожидается. Использование DynamicObject требует от меня, чтобы все клиенты этого приложения использовали «динамический» вместо «ISecondaryInterface».

Есть ли способ получить прокси-объект, такой, что, когда он оборачивает A, он объявляет (статически?), Что поддерживает интерфейс A; и когда он оборачивает B, он объявляет, что поддерживает интерфейс B?

ОБНОВЛЕНИЕ 2

Например:

class MySecretProxy : DynamicObject, ISecondaryInterface
{
    public override void TryInvokeMember(...) { .. }

    // no declaration of Bar -- let it be handled by TryInvokeMember
 }

Ответы [ 5 ]

6 голосов
/ 06 июня 2011

.NET 4 DynamicObject может помочь вам в достижении этого.

Ранее платформа .NET могла использовать:

  • Aspect #
  • Encase AOP
  • Spring.NET
  • Aspect.NET
  • AspectDNG
  • Динамический прокси
  • Compose *
  • Loom.NET
  • PostSharp

Каждая из этих платформ использует ряд методов для внедрения кода как до, так и после выполнения метода.Обычно они подразделяются на 4 категории.

  • Инъекция MSIL - Здесь мы вводим код MSIL в тело выполняемого метода.(Пост резкий)
  • Динамическое внедрение во время выполнения - Используя методы, такие как отражение, мы вызываем методы динамически.
  • Внедрение в конструктор типов - Связано с внедрением во время выполнения, мы создаем тип на основе типа, который мы хотим прокси, а затем маршалируем запросы через этот тип.(Динамический прокси)
  • Инъекция контейнера - запросы проходят через контейнер, который вызывает код до и после выполнения нашего метода.

См. полная статья .

Я знаю, что Castle Project Dynamic Proxy часто используется (как в Moq просто дляназовите один большой проект).


ОТВЕТИТЬ НА ОБНОВЛЕННУЮ ТЕМУ

То, что вы написали, не скомпилируется. Динамические прокси - это сгенерированный во время выполнения код, поэтому вам придется создать конкретный экземпляр класса, который вы так или иначе проксируете.Может быть, вы хотите сделать AOP (аспектно-ориентированное программирование).

class MySecretProxy<T> : DynamicObject, T where T : new()
{
    private T _instance = new T();

    public override void TryInvokeMember(...) { ... }
}

MySecretProxy<Bar> bar;
3 голосов
/ 04 января 2011

Вы смотрели на DynamicProxy проекта Castle? Это может обеспечить то, чего вы в конечном итоге пытаетесь достичь. Смотри http://www.castleproject.org/dynamicproxy/index.html

Это также открытый исходный код, так что вы можете даже раскошелиться, если потребуется.

1 голос
/ 14 июля 2011

Вы можете сделать это с RealProxy, если целевой Тип является интерфейсом или является производным от MarshalByRefObject.

0 голосов
/ 04 января 2011

Я знаю прокси, которые nhibernate использовал для отложенной загрузки

Castle

Linfu

Spring ByteCode

0 голосов
/ 04 января 2011

Возможно, вы захотите взглянуть на linfu , который содержит механизм динамического прокси.

...