Инициализация сборки .NET во время выполнения - PullRequest
0 голосов
/ 27 февраля 2012

Во время выполнения мне нужно, чтобы мои загруженные сборки C ++ могли регистрировать информацию о своих версиях в приложении верхнего уровня.Я думал о чем-то вроде:

     array<System::Reflection::Assembly^>^ assemblies = System::AppDomain::CurrentDomain->GetAssemblies();

     for each(System::Reflection::Assembly^ assembly in assemblies)
     {}

Но как вы можете определить, какие мои сборки, а какие системные сборки.Есть ли какой-нибудь способ добавить статический метод в мои классы, который может вызывать этот код?

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

public ref class Foo
{
public:

  Foo()
  {
  };

private:

};

public ref class InitOnLoad : System::Attribute 
{ 
public:

  InitOnLoad()
  {
     Foo ^foo = gcnew Foo();
     System::Type^ thisType = foo->GetType();

     // get a list of types which are marked with the InitOnLoad attribute
     array<System::Reflection::Assembly^>^ assemblies = System::AppDomain::CurrentDomain->GetAssemblies();

     for each(System::Reflection::Assembly^ assembly in assemblies)
     {
        try
        {
           System::Type^ type = System::Type::GetType("UtilsDotNet.Foo");

           array<Object^>^ attributes = assembly->GetCustomAttributes(type, false);

           if(attributes->Length > 0)
           {
              auto field =
                 type->GetFields(
                 System::Reflection::BindingFlags::Static | 
                 System::Reflection::BindingFlags::Public | 
                 System::Reflection::BindingFlags::NonPublic);
           }

        }
        catch (...)
        {
        }
     }
  }
};

1 Ответ

1 голос
/ 27 февраля 2012

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

Мой синтаксис может быть неправильным, но ...

System::Type^ type = System::Type::GetType("UtilsDotNet.Foo");
array<Object^>^ attributes = assembly->GetCustomAttributes(type, false);

должно быть

array<Object^>^ attributes = assembly->GetCustomAttributes(__typeof(InitOnLoad), false);

Я не уверен, что в C ++ можно пометить сборку атрибутом, но в C # можно поместить эту строку в файл Assembly.cs (в папке Properties)

[assembly:  InitOnLoad()]

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

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

...