У меня проблема в моем проекте с использованием типов из F # в библиотеке C #.
У меня есть приложение, которое в основном состоит из следующих основных частей:
- coreбиблиотека (.NET Standard 2.1);
- Клиент WPF.
Библиотека core содержит все независимые от платформы логику и модели представления и может использоваться влюбой вид клиентов пользовательского интерфейса. Приложение разработано для расширения и может динамически подключать расширения перед загрузкой пользовательского интерфейса. На данный момент он просто загружает DLL из определенной папки через Assembly.LoadFrom . Единственное требование для того, чтобы dll был распознан как расширение, - это предоставить специальный класс, производный от Module или Extension классов, определенных в ядро библиотека. И он отлично работает при загрузке сборок, написанных на C #. Но я столкнулся с очень странным поведением, когда пытался использовать расширение, написанное на F #. Допустим, у меня есть интерфейс IRecognitionProcessor , который определен в моей основной библиотеке. Вот некоторые из его членов:
public interface IRecognitionProcessor
{
string Name { get; }
string Description { get; }
bool ContainsFace(Bitmap bitmap);
FaceDetail[] ExtractDetails(Bitmap bitmap);
/* more members goes here */
}
В моем новом расширении, обеспечивающем пользовательское распознавание на основе EmguCV библиотеки для .NET, у меня есть потомок IRecognitionProcessor что в результате будет извлечено и сохранено в специальном контейнере. Расширение написано на F #, как я уже упоминал ранее. Вот краткий пример реализации:
type EmguFaceRecognition() =
interface IRecognitionProcessor with
member this.Name : string = "EmguCV"
member this.Description : string = "EmguCV face recognition processor"
member this.ContainsFace (bitmap : Bitmap) : bool =
//code goes here
member this.ExtractDetails (bitmap : Bitmap) : FaceDetail array =
//code goes here
// other implementations
Он загружается правильно без каких-либо ошибок, и все сборки, которые идут вместе с ним, также загружаются нормально. Проблема возникает, когда я выбираю все процессоры из моих подключенных расширений. Вот упрощенное представление кода, который описывает модуль и как он предоставляет процессор:
type EmguRecognitionModule() =
inherit RecognitionModule()
override this.GetRecognitionProcessor() : IRecognitionProcessor =
new EmguFaceRecognition() :> IRecognitionProcessor
// more code goes here
Когда загружается новый модуль - его процессор извлекается и сохраняется в хранилище. Оба шага с созданием экземпляра модуля с помощью Activator.CreateInstance и извлечения его процессора с помощью GetRecognitionProcessor метода работают нормально. Это метод, который заполняет один из наборов процессоров моей модели представления:
public void PopulateRecognitionProcessors(IEnumerable<IRecognitionProcessor> processors, AccessToken accessToken)
{
if (accessToken != _parentAccessToken)
throw new AccessViolationException("Attempt to set recognition processors from outside of the parent");
_recognitionProcessors.Clear();
_recognitionProcessors.AddRange(processors);
SelectedProcessor = _recognitionProcessors.FirstOrDefault();
}
Довольно простой, хотя он плохо работает, когда процессоры приходят из библиотеки F #. Даже если есть процессоры, свойство SelectedProcessor не будет назначено первому процессору вообще, оно все равно будет null . Когда я поставил точку останова и попытался наблюдать свойства процессоров, хранящихся в коллекции - проверка не показала ни одно из свойств. Вот ссылка на пример проверки свойств, которую я сделал в JetBrains Rider . Но когда я использую окно Evaluate , я могу получить доступ ко всем свойствам и методам объекта, и IntelliSense работает отлично. Ссылка на изображение с примером оценки . Вся эта ситуация заставляет меня чувствовать себя глупым. Просто столкнулся с этой проблемой впервые. Ранее все мои попытки использовать типы, определенные в библиотеках F #, увенчались успехом. Но это исключение. Я вижу, что использование типа, производного от абстрактного, работает хорошо. Но типа, который реализует интерфейс, как-то нет.