Получить ссылку на сборку без отражения или известного типа

В моем текущем дизайне фреймворка я просматриваю все типы конкретных сборок и работаю на основе найденных типов. Сборки, которые он ищет, определяются загрузчиком/инициализатором приложения. Сборки скомпилированы, поэтому на них можно строго ссылаться через:typeof(SomeTypeInTheAssembly).Assembly. Это хорошо, потому что код загрузчика имеет строгую ссылку на тип в сборке, и нет возни с полными именами в виде встроенных строк, которые необходимо вручную поддерживать с датой -до -, если полное имя сборки изменится.. Но мне не нравилось ссылаться на какой-то совершенно не связанный тип в сборке и зависеть от его наличия. (Что, если он переместится на другую сборку? Что, если мы устарели/удалим тип? Изменить его пространство имен? )В коде это тоже выглядит немного странно:

FrameworkAssemblyReader.Read(typeof(SomeAssemblyNamespace.SubNamespace.GraphingCalculator).Assembly);

Теперь в моем коде начальной загрузки у меня есть прямая зависимость (, хотя довольно тривиальная зависимость )от GraphingCalculator, которая не имеет ничего общего с стадией начальной загрузки (и как GraphingCalculator, она определенно не имеет ничего общего с получение ссылок на сборки ). Чтобы этого избежать, в каждой сборке, которую я намерен использовать таким образом, я добавил в их корень класс:

namespace SomeAssemblyNamespace
{
    public static class AssemblyReference
    {
        public static System.Reflection.Assembly Get
        {
            get
            {
                return typeof(AssemblyReference).Assembly;
            }
        }
    }
}

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

FrameworkAssemblyReader.Read(SomeAssembly.AssemblyReference.Get);

Но теперь у меня есть около дюжины или около того сборок с копированием/вставкой этого класса AssemblyReference, и я ожидаю, что он будет продолжать расти по мере того, как приложения будут создаваться поверх фреймворка. Итак, мой вопрос: есть ли хороший способ избежать дублирования класса AssemblyReferenceи по-прежнему программно передавать ссылки на сборки в базовую структуру, но при этом избегать нечеткости указания на какой-то произвольный/несвязанный тип в целевой сборке?Мои гуглы, кажется, говорят мне, что нет API или языковой функции, которая позволяет мне строго указывать на сборку (, например typeofдля классов ), но я надеюсь, что кто-то здесь придумал лучшее решение, чем я есть, что позволяет избежать дублирования класса/кода. Также следует отметить, что код иногда компилируется для Silverlight, поэтому я знаю, что это может привести к ограничению некоторых API/методов. Спасибо!

РЕДАКТИРОВАТЬ :Просто чтобы добавить еще один гаечный ключ, основываясь на ответе «енота», я должен упомянуть, что я не всегда загружаю одни и те же сборки. Например, у меня может быть сборка CarBuilding, которая применима для некоторых приложений, но не для всех. Загрузчики должны сказать мне, какие из них они хотят использовать (, а также любые пользовательские, которые использует разработчик )

. EDITx2 :Чтобы ответить на вопрос Джона Скита :Клиенты (или мы внутри компании )создадут любые проекты/DLL, которые они захотят поддерживать в своих приложениях. В свою очередь, эти проекты будут ссылаться на внутреннюю базовую структуру. Их проекты могут содержать ресурсы (3D-файлы, изображения, текст, локализацию и т. д. )и плагины -esque-классы (они реализуют сценарии, которые мы обнаруживаем и создаем/выполняем по мере необходимости. в течение всего срока службы приложения ). Кроме того, наша система предоставляет дополнительные модули (библиотеки DLL ), которые содержат подключаемые модули/контент многократного использования, которые клиенты (или мы )можем использовать при создании конкретных приложений. Таким образом, вы можете увидеть такую ​​структуру проекта, как:

Solution
    ->MyAppBootstrapper_Android
        ->MyAppGUI_Android
        ->MyAppFramework
        ->MyAppResources
        ->MyAppAdditionalResources_Android

    ->MyAppBootstrapper_Silverlight
        ->MyAppGUI_Silverlight
        ->MyAppFramework
        ->MyAppResources
        ->MyAppAdditionalResources_Silverlight
        ->BaseFrameworkGraphingModule

Проекты загрузчика подключают зависимости и указывают, какие проекты/dll (сборки )должны быть предоставлены базовой структуре для обнаружения. Обратите внимание, что в этом случае «MyApp» использует собственную мини-инфраструктуру -и общие ресурсы как в сборках Android, так и в сборках Silverlight, но обе имеют свои собственные ссылки, независимые друг от друга.Silverlight использует преимущества BaseFrameworkGraphingModule, и у них есть свои собственные ресурсы, специфичные для платформы.

Так вот в загрузчиках в проектах выглядят примерно так (пусть и упрощенно):

namespace MyAppBootstrapper_Android
{
    public class Bootstrapper
    {
        public void Setup()
        {
            FrameworkAssemblyReader.Read(MyAppGUI_Android.AssemblyReference.Get);
            FrameworkAssemblyReader.Read(MyAppFramework.AssemblyReference.Get);
            FrameworkAssemblyReader.Read(MyAppResources.AssemblyReference.Get);
            FrameworkAssemblyReader.Read(MyAppAdditionalResources_Android.AssemblyReference.Get);
        }
    }
}

namespace MyAppBootstrapper_Silverlight
{
    public class Bootstrapper
    {
        public void Setup()
        {
            FrameworkAssemblyReader.Read(MyAppGUI_Silverlight.AssemblyReference.Get);
            FrameworkAssemblyReader.Read(MyAppFramework.AssemblyReference.Get);
            FrameworkAssemblyReader.Read(MyAppResources.AssemblyReference.Get);
            FrameworkAssemblyReader.Read(MyAppAdditionalResources_Android.AssemblyReference.Get);
            FrameworkAssemblyReader.Read(BaseFrameworkGraphingModule.AssemblyReference.Get);
        }
    }
}

Таким образом, для каждого приложения, созданного поверх базового фреймворка, создается загрузчик, который указывает, какие сборки включать (и какую-то другую не относящуюся к делу работу по подключению ). Чтобы конкретно ответить на этот вопрос, в проекте есть ссылки на время компиляции -для каждой необходимой сборки (, это выполняет двойную функцию, поскольку гарантирует, что все библиотеки DLL упакованы вместе для развертывания Android/Silverlight ), поскольку они не загружаются динамически в на смартфоне пользователя или в приложении Silverlight, но упакованы в первоначальную загрузку. Ваш вопрос о том, как загрузчики узнают, какие сборки использовать, хорошо, что разработчик знает и выполняет необходимые вызовы FrameworkAssemblyReader.Read. Надеюсь, это поможет! Спасибо, что нашли время, чтобы посмотреть на него. У меня такое ощущение, что я делаю слишком много из ничего (или вообще упускаю гораздо лучшее решение/дизайн ).

Наконец, я позабыл (тупо )упомянуть, что мы также компилируем с помощью Mono для Android, а в ближайшем будущем и WPF. WinRT, скорее всего, появится в будущем, но я буду счастлив перейти по этому мосту, когда дело дойдет до этого. Однако, в целом, поскольку каждая из них компилируется по-своему со своими собственными функциями платформы, я не возражаю ужасно , если разные платформы по-разному извлекают ссылки на сборки; хотя было бы неплохо, если бы между платформами был единый синтаксис.

EDITx3 :Да, еще один. Я упомянул, но не уточнил на примере, что не все проекты нуждаются или должны читаться базовым фреймворком. Например, служебные программы или проекты бизнес-логики с кодом, не относящимся к базовой платформе, но относящимся к клиентскому приложению. Итак, из приведенного выше примера:

Solution
    ->MyAppBootstrapper_Android
        ->MyAppGUI_Android
        ->MyAppFramework
        ->MyAppResources
        ->MyAppAdditionalResources_Android
        ->MyCompanySharedUtilities

    ->MyAppBootstrapper_Silverlight
        ->MyAppGUI_Silverlight
        ->MyAppFramework
        ->MyAppResources
        ->MyAppAdditionalResources_Silverlight
        ->BaseFrameworkGraphingModule
        ->MyCompanySharedUtilities

MyCompanySharedUtilitiesможет использоваться MyAppGUI _Silverlight,и MyAppFramework, но разработчик может не запустить его через FrameworkAssemblyReader.Read, потому что он содержит, скажем, только проприетарные реализации некоторых математических или бизнес-правил.

8
задан Chris Sinclair 3 July 2012 в 13:03
поделиться