Тип интерфейса C# Reflection и единство

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

var ourProcess = container.Resolve<IProcessing>(new ResolverOverride[] { new ParameterOverride("parameter1", value1) });
ourProcess.ExecuteProcess(parameterValues); 
// parameterValues a string list, all of my processes use this main calling mechanism.
// there are many other interfaces i a number of other assemblies along with IProcessing

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

Я пробовал использовать отражение в духе ...

Assembly asm = Assembly.LoadFrom("CompName.Application.Processing.dll");
foreach (Type type in asm.GetTypes())
{
    if (type.GetInterface("IProcessing") != null)
    {
        var ourProcess = container.Resolve<type> (new ResolverOverride[] { new ParameterOverride("parameter1", value1) });
        oSummary = ourProcess.ExecuteProcess(parameterValues);
    }
}
// at runtime we will know the strings "CompName.Application.Processing.dll" and "IProcessing"

Однако во время компиляции мы получаем, что «тип - это переменная, но используется как тип», достаточно справедливо.

Я пробовал typeof (type), type.GetType () и Type (type) безрезультатно, и все это приводило к различным ошибкам компилятора.

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

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

Любой вклад приветствуется, спасибо.

Проблема с тем, как вы вызываете Resolve, заключается в том, что вам нужно использовать конкретный тип с универсальными шаблонами. Если у вас нет конкретного типа, вам нужно собрать MethodInfo, используя тип container, и заполнить параметры типа с помощью MakeGenericMethod. Я не уверен, поддерживает ли его Unity, но Autofac может получить IEnumerable из своего метода Resolve, содержащий все, что реализует ваш тип.

Julian Goldsmith 19.09.2018 17:39
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
1
721
1

Ответы 1

Если у вас уже есть Тип класса, вы можете просто использовать

var processor = Activator.CreateInstance(type, param[] object args) as IProcessing;

Редактировать: или вы можете использовать «динамический», если вы готовы понести ущерб производительности, связанный с этим. И если вас устраивает тот факт, что вам не понадобится помощь Intellisense во время написания кода.

var processor = Activator.CreateInstance(type, param[] object args) as dynamic;
processor.ExecuteProcess(parameterValues);

Привет, Андреас, как уже упоминалось, я не могу напрямую ссылаться на тип IProcessing, для этого мне пришлось бы включить ссылку на сборку, содержащую тип IProcessing, в мою основную сборку. Я не хочу этого делать.

K Hurst 19.09.2018 17:24

но вы уже загрузили сборку в память с помощью Assembly.LoadFrom ("..."), вам не нужно добавлять ссылку при использовании "связывания" во время выполнения. Однако вам потребуется IProcessing в сборке, на которую указывает ссылка.

Andreas 19.09.2018 17:29

Привет, Андреас! «Однако вам понадобится IProcessing в сборке, на которую указывает ссылка ...» Это то, от чего я пытаюсь уйти. Та, К

K Hurst 20.09.2018 08:47

Разве вы не можете хотя бы иметь интерфейс в сборке, на которую ссылаются? Как другой код работает с экземплярами IProcessing, если у вас нет хотя бы ссылки на интерфейс? Или вы всегда используете «динамический»?

Andreas 20.09.2018 13:52

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

K Hurst 20.09.2018 14:17

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

Andreas 20.09.2018 15:06

Другие вопросы по теме