2009-12-07 2 views
1

У меня есть сборка .NET, которая определила тип T во время компиляции, и я создал экземпляр объекта my_t в качестве экземпляра этого типа.Замена типа .NET во время выполнения

Мне интересно, можно ли в .NET использовать службы компилятора времени выполнения для повторной компиляции этого класса, а затем загрузить новое определение класса в текущую исполняемую сборку, поэтому, когда я вызываю методы с my_t, они будут используйте новый код.

Я не меняю подписи ни одного из методов, только тела метода.

Любые гуру из .NET знают, возможно ли это? Заранее благодарю за любую помощь!

+2

Я бы никогда не сделал что-то подобное. Почему бы не использовать наследование? – ChaosPandion

+0

Да, какой прецедент? Почему бы не использовать архитектуру плагина? Скомпилируйте свой динамический плагин и загрузите его, очевидно, проходя свой плагин. –

+0

Я согласен с предыдущим оратором. таким образом, когда я вызываю метод в классе, я не могу точно знать, что он будет делать * даже если у меня есть доступ к коду *. звучит хаотично, и это то, что ОО - все о предотвращении. то, что вы хотите, возможно, может быть достигнуто с помощью шаблона инъекции зависимостей. –

ответ

1

Объект .NET не может изменять тип во время выполнения; это фундаментальное предположение в CLR.

Несколько предложений:

  1. Написать код T для переадресации вызовов на правильный тип в зависимости от обстоятельств. Он может перенаправлять тип, который компилируется во время выполнения, если вы хотите.
  2. Используйте какой-то ориентированный на аспект или динамический прокси-каркас для автоматизации (1) для вас
  3. Если такой переадресация не подходит, я считаю, что есть API-интерфейс профилирования .NET, доступный для native, который позволяет вам перехватывать процесс JIT. Все, что я знаю об этом, - это то, что такие инструменты, как NCover, могут вводить свой машинный код таким образом.
+0

Я думаю, что ваше предложение # 1 очень многообещающее - у меня есть прототип, работающий сейчас. Один вопрос заключается в том, вызывает ли вызов my_t.GetType(). GetMethod («my_method_name») - это серьезное поражение производительности по сравнению с вызовом, скажем, my_t.my_method_name напрямую. Есть идеи? – Mike

+0

Это ужасный удар производительности. Взгляните на проект Ashish.s's Castle Dynamic Proxy. –

0

Чтобы расширить на мой комментарий:

public class Base 
{ 
    public virtual void Method() 
    { 

    } 
} 

public class Sub : Base 
{ 
    public override void Method() 
    { 

    } 
} 

public void DoStuff<T>() where T : Base, new() 
{ 
    var instance = new T(); 
    instance.Method(); 
} 
3

Я не уверен, что это возможно, но если это так, это звучит как ужасно грязный раствор.

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

+0

+1. Взгляните на http://www.codeplex.com/MEF – TrueWill

2

вы можете использовать динамический прокси-замок для создания прокси-сервера вашего класса. Прокси-сервер - это новый тип, который позволит вам внедрить новую реализацию, но все, что вы хотите ввести, должно быть объявлено как виртуальное.

+0

Интересно - я предполагаю, что вы говорите о http://www.castleproject.org/dynamicproxy/index.html - вы использовали это? Как влияет производительность, если вам это известно? Спасибо! – Mike

+0

Я использовал его в одном из моих проектов, влияние на производительность должно стабилизироваться, поскольку он фактически генерирует код и компилирует его в сборку для ваших типов. –

6

Вы можете реализации метода замены, но ТОЛЬКО при работе небезопасного кода является вариант, и методы, которые вы хотите поменять не были NGen'd или «Zapped».

Основная процедура довольно проста: вы меняете адрес памяти, где находится код JIT'd метода, с адресом памяти кода JIT'-кода другого метода (вы также можете заставить CLR использовать JIT-методы в на первом месте, чтобы избежать странной предпосылки).

Существует большой проект проверка концепции на codeproject.com: http://www.codeproject.com/Articles/37549/CLR-Injection-Runtime-Method-Replacer

Сходи, проверь!

+3

FINALLY, один фактический ответ на вопрос. Благодаря! – galets

+0

Добро пожаловать! :) – BrainSlugs83