Я на самом деле работаю над проектом с использованием WPF, MEF и Prism. Когда я запускаю приложение, мне нужно экспортировать модуль из контейнера, чтобы открыть окно конфигурации до отображения основного окна. Таким образом, код выглядит так:
protected override void OnStartup(StartupEventArgs e)
{ base.OnStartup(e);
Bootstrapper bootstrapper = new Bootstrapper();
bootstrapper.Run();
var window = bootstrapper.statcontainer.GetExport<Configshell>();
var configview = bootstrapper.statcontainer.GetExport<Module.Module1.View.ConfigView>();
window.Value.Show();
Keyboard.Focus(configview.Value.ok_button); }
Где bootstrapper.statcontainer является публичным CompositeContainer (выделенным "Maincontainer" MEFBootstrapper в методе CreateContainer-Method). Я использую его для экспорта модулей при запуске. Теперь в GetExport() я получаю следующее первое исключение:
GetExportedValue не может быть вызван перед обязательным импортом "MyApp.Module.Module2.ViewModels.Module2_Functions..ctor (Параметр =" C_Aggregator ", ContractName =" Microsoft.Practices.Prism.PubSubEvents.IEventAggregator ")".
И вот как выглядит ctor:
[Import]
public IEventAggregator Configaggregator;
[ImportingConstructor]
public Module2_Functions(IEventAggregator C_Aggregator)
{
this.Configaggregator = C_Aggregator;
Configaggregator.GetEvent<FromConfigWindow>();
FromConfigWindow.Instance.Subscribe(receiveStatusFromConfigWindow);
Configaggregator.GetEvent<ToConfigWindow>();
}
Я использую EventAggregator, чтобы опубликовать конфигурацию и иметь тот же ctor в другом модуле. Путаница заключается в том, что он работал так, пока я не добавил еще один полностью независимый импорт в этот ViewModel. Вот как выглядит скрипт ConfigwindowViewModel:
[ImportingConstructor]
public ConfigVM(IEventAggregator C_aggregator)
{
this.Configaggregator = C_aggregator;
Configaggregator.GetEvent<ToConfigWindow>();
ToConfigWindow.Instance.Subscribe(actualizeCompStatus);
Configaggregator.GetEvent<FromConfigWindow>();
}
[Import]
public IEventAggregator Configaggregator;
Эти два события выглядят так, и оба уже работали до 2 дней назад ;-)
[Export]
public class FromConfigWindow : PubSubEvent<Int16>
{
private static readonly EventAggregator _eventAggregator;
private static readonly FromConfigWindow _event;
static FromConfigWindow()
{
_eventAggregator = new EventAggregator();
_event = _eventAggregator.GetEvent<FromConfigWindow>();
}
public static FromConfigWindow Instance
{
get { return _event; }
}
}
[Export]
public class ToConfigWindow : PubSubEvent<Int16>
{
private static readonly EventAggregator _eventAggregator;
private static readonly ToConfigWindow _event;
static ToConfigWindow()
{
_eventAggregator = new EventAggregator();
_event = _eventAggregator.GetEvent<ToConfigWindow>();
}
public static ToConfigWindow Instance
{
get { return _event; }
}
}
Поэтому, наконец, проблема выглядит так, как EventAggregator не получает instanciated, и поэтому исключение получает. Но как я могу обойти это? Или я делаю что-то неправильно в связи с агрегатором в конструкторах?
Я уже пытался модифицировать все аргументы конструктора с помощью атрибута [Import], это также порождало то же исключение или удаляло все атрибуты [Import] из объектов Configaggregator IEventAggregator в ViewModels.
Проблема аналогична этой ссылке здесь, но в моем случае это происходит с EventAggregator из структуры Prism.
Скажите, пожалуйста, если я должен предоставить вам больше частей кода.
Я не уверен, почему вы PubSubEvents
свои PubSubEvents
или ссылаетесь на статический новый EventAggregator
. Вы должны использовать только один экземпляр EventAggregator
(в этом примере), который вы получите из своего контейнера (Prism поместит его там для вас).
Вы должны вернуться к основам и прочитать отличную документацию Prism. Раздел 9 "Связь между слабосвязанными компонентами" для обзора EventAggregator и PubSubEvents.
Если вы хотите создать проект "Голые кости", который имитирует проблему, с которой вы столкнулись, и загрузите ее где-нибудь, я с удовольствием посмотрю на нее.
Похоже, что ошибка связана с тем, что вы не выполнили весь свой импорт до начала операций над ними. Я согласен с ChrisO, вы должны вернуться и проверить документы. Здесь происходит много вещей, которые кажутся слишком сложными. Почему в нем появился new EventAggregator()
? MEF должен импортировать эту зависимость для вас. Почему все возится с контейнером и получает экспорт? Кажется, вы делаете много работы, о которой должны заботиться MEF и Prism.
var container = ServiceLocator.Current.GetInstance(CompositionContainer);
Я не проверял это до сих пор, просто нашел это здесь сообщением Мигеля Бронзовича. Спасибо за вашу помощь!
public IEventAggregator Configaggregator = ServiceLocator.Current.GetInstance<IEventAggregator>()
; Спасибо за вашу помощь!