Graeme_Grant
Вам не нужно использовать отражение с MEF, вы просто экспортируете и импортируете данные для совместного использования - данные могут существовать в DLL/EXE вне основного приложения. Пока MEF может составлять, данные будут видны. Это то, что мы сделали в другом Решение MEF[^] где отражение было запрошено для системы плагинов, и плагины автоматически загружаются, когда DLL/EXE помещается в папку основного приложения.
Итак, ответ заключается в том, чтобы создать класс для хранения ваших пользовательских данных в отдельном классе (репозитории), определить Export
с собой PartCreationPolicy(CreationPolicy.Shared)
Это создаст статический/общий объект. Вот вам пример:
public interface IUserRepository
{
string UserName { get; set; }
}
[Export(typeof(IUserRepository)),
PartCreationPolicy(CreationPolicy.Shared)]
public class UserRepository : ObservableBase, IUserRepository
{
private string userName = "**Not Set**";
public string UserName
{
get => userName;
set => Set(ref userName, value);
}
}
Примечание: приведенный выше код не является потокобезопасным. Я оставлю это на ваше усмотрение, если вы этого потребуете.
Вот
ObservableBase
класс:
public abstract class ObservableBase : INotifyPropertyChanged
{
public void Set<TValue>(ref TValue field, TValue newValue, [CallerMemberName] string propertyName = "")
{
if (EqualityComparer<TValue>.Default.Equals(field, default(TValue)) || !field.Equals(newValue))
{
field = newValue;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
public event PropertyChangedEventHandler PropertyChanged;
public bool IsInDesignMode => DesignerProperties.GetIsInDesignMode(new DependencyObject());
}
А теперь ты
import
то
UserRepository
:
[Import(typeof(IUserRepository), RequiredCreationPolicy = CreationPolicy.Shared)]
public IUserRepository Repo { get; set; }
... и пользовательские данные теперь совместно используются везде, где указано выше
Import
предназначенный:
Repo.UserName = "MainUser";
Никакого кодирования отражения от вас не требуется, так как все это обрабатывается MEF. Наслаждайтесь!
PS: да, MEF использует отражение, так что вам это не нужно! ;)
JohnMeers
Я понимаю это, но я использую ImportMany, так как у меня есть несколько плагинов, которые все являются IFunctions. Метаданные позволяют мне найти правильный вариант, но это все еще IFunction, и видны только общие методы IFunction и т. д., а не те, которые предназначены для конкретной функции NewUser. Без ссылки на NewUser (что отрицало бы цель использования MEF) Я не могу привести IFunction к NewUserViewModel, хотя это так.
Я сдался и реализовал общий метод IFunction 'Test(object[])' для установки свойств. Очень неэлегантно так что если у кого то есть лучший способ это будет приветствоваться
Graeme_Grant
То, что я предложил, разделяет пользовательские данные. Таким образом, если вы хотите выполнить метод против пользовательских данных, вам не нужно знать, какая модель представления является UserRepository
содержит главную ссылку, поэтому вы вызываете метод на общем ресурсе. UserRepository
вместо.
JohnMeers
Спасибо, я не до конца оценил ваш ответ, он значительно отличается от того, что я пробовал. Надо подумать об этом. Если я правильно понимаю, он отделяет данные от виртуальной машины и централизует их, что звучит так, как будто это был бы хороший шаг MVVM, но повлияет на большее, чем интеграционное тестирование.
Graeme_Grant
Разделение проблем - то есть: удаление уровня данных из вашей логики бизнес-уровня.
То, что он также позволяет, - это замена репозитория и реализация макетного тестирования или изменение уровня данных, а также его интеграционное тестирование.