Как мне прикрепить метод к динамически созданному типу C # во время выполнения? - PullRequest
7 голосов
/ 02 апреля 2009

Я был обременен использованием внутренней библиотеки доступа к данным, которая эффективно передает XML в хранимую процедуру, которая возвращает XML. Я ничего не могу с этим поделать. Я пытался получить одобрение ActiveRecord, но мой запрос был отклонен. Однако, используя превосходный код, предоставленный в http://blog.bodurov.com/Post.aspx?postID=27,, я добавил в IEnumerable метод расширения, который преобразует пары ключ-значение, которые я создаю из рваного XML, и возвращаю его в строго типизированные объекты с именами свойств!

Это:

dict["keyName1"]

становится

MyObject.keyName1

Теперь интерфейс поддерживает привязку данных! Довольно круто! Я бы хотел сделать еще один шаг вперед. Я хочу, чтобы у объектов, которые излучаются, тоже были методы Save (), чтобы я мог использовать шаблон ActiveRecord и предоставить своим веб-разработчикам интуитивно понятный объектный слой для использования из ASP.net.

Как написать метод в Visual Studio, в исходном коде и присоединить его во время выполнения к выдаваемым объектам? Я не заинтересован (или квалифицирован для) написания ассемблера или IL. Я хотел бы сделать это в C #. Это мой первый вопрос о StackOverflow, и я публикую его в соответствии с утвержденным компанией IE6, поэтому будьте осторожны.

Ответы [ 2 ]

2 голосов
/ 02 апреля 2009

Из того, что я собрал в этой статье, он создает анонимные типы для вас, и вы используете это для получения значений. Если это так, то нет простого способа добавить методы к этим объектам. Однако, если структура XML будет одинаковой при каждом выполнении SP, почему бы не создать конкретный класс со всеми необходимыми свойствами и заполнить коллекцию этих объектов самим XML. Таким образом, вы можете легко добавлять любые нужные вам методы непосредственно в класс ...

РЕДАКТИРОВАТЬ: Основываясь на нашей дискуссии в комментариях, вот мысль:

В этом коде при создании типа вы используете: ModuleBuilder.DefineType. Существует перегрузка для DefineType, которая принимает тип для расширения. Link. . Поэтому создайте интерфейс (он не должен содержать никаких методов), а когда вы динамически создаете тип, расширяйте этот интерфейс с помощью перегрузки, с которой я вас связал. Затем создайте метод расширения для этого интерфейса, который выполняет функцию Save ().

Существует другая перегрузка, которая может представлять интерес для расширения типа и интерфейсов:

http://msdn.microsoft.com/en-us/library/f53tx4x8.aspx

РЕДАКТИРОВАТЬ 2: Пример кода:

Сначала создайте интерфейс:

public interface ISaveExtentable //I suck at naming stuff :-p
{

}

Затем в коде, который вам понравился на этом сайте, вы найдете метод с именем: GetTypeBuilder. Измените это на это:

        private static TypeBuilder GetTypeBuilder(string typeSigniture)
        {
            AssemblyName an = new AssemblyName("TempAssembly" + typeSigniture);
            AssemblyBuilder assemblyBuilder =
                AppDomain.CurrentDomain.DefineDynamicAssembly(
                    an, AssemblyBuilderAccess.Run);
            ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("MainModule");

            TypeBuilder tb = moduleBuilder.DefineType("TempType" + typeSigniture
                                , TypeAttributes.Public |
                                TypeAttributes.Class |
                                TypeAttributes.AutoClass |
                                TypeAttributes.AnsiClass |
                                TypeAttributes.BeforeFieldInit |
                                TypeAttributes.AutoLayout
                                , typeof(object), new Type[] {typeof(ISaveExtentable)});
            return tb;
        }

Затем создайте метод расширения для этого интерфейса для сохранения:

    public static class SaveExtendableExtensions
    {
          public static void Save(this ISaveExtentable ise)
          {
              //implement save functionality. 
          }
    }

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

1 голос
/ 19 ноября 2009

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...