为什么用户没有收到Prism EventAggregator生成的松散耦合事件?

时间:2016-03-07 09:44:43

标签: c# wpf events prism

在我的Prism 6 WPF MVVM模块化应用程序(使用Unity DI)中,我希望使用松耦合事件在模块之间进行通信 - 一个模块是发布者,另一个模块是订阅者。在AuthorizationViewModel类的发布者方面,我特别具有以下方法:

public class AuthorizationViewModel : BindableBase
{
    . . . . .
    // This method is called from the command method when user clicks button in the view.
    private void authenticateUser(string userName, string userPassword, Action<UserAuthorizationLevel> successCallback, Action<string> failureCallback)
    {
        Task task = Task.Run(() =>
              this.getUsers((users) =>
              {
                  // Get authenticated user information.
                  var userAuthenticated = GetUserByNameAndPassword(userName, userPassword, users);
                  // Call method publishing loosely coupled event if the user exists. Else display the error message.
                  if (userAuthenticated != null)
                      successCallback(userAuthenticated.AuthorizationLevel);
                  else
                      failureCallback("Authentification failed.");
              }));
    }
    . . . . .
}

以下是AuthorizationViewModel类中的successCalback定义:

private void successCalback(UserAuthorizationLevel authorizationLevel)
{
    // Publish loosely coupled event.
    this._eventAggregator.GetEvent<UserAuthorizationLevelDeterminedEvent>().Publish(authorizationLevel);
}

UserAuthorizationLevel这里是在我的应用程序解决方案的公共位置定义的枚举类型,我不在这里显示它。 UserAuthorizationLevelDeterminedEvent是在我的应用程序解决方案的公共位置定义的事件类型。下面我展示它:

public class UserAuthorizationLevelDeterminedEvent : PubSubEvent<UserAuthorizationLevel>
{
}

successCalback方法在必要时及其代码行

运行
this._eventAggregator.GetEvent<UserAuthorizationLevelDeterminedEvent>().Publish(authorizationLevel);

执行正常以便发布事件但订阅者根本不对事件作出反应!订户方面的活动没有回复!下面我在用户端显示代码:

public class CalibrationNavigationItemViewModel : BindableBase
{
    . . . . .
    private IEventAggregator _eventAggregator;
    . . . . .
    // The constructor; creates instance of CalibrationNavigationItemViewModel.
    public CalibrationNavigationItemViewModel(IRegionManager regionManager, IEventAggregator eventAggregator)
    {
        . . . . .
        this._eventAggregator = eventAggregator;
        this._eventAggregator.GetEvent<UserAuthorizationLevelDeterminedEvent>().Subscribe(this.setRadiobuttonVisualStatus, ThreadOption.BackgroundThread);
        . . . . .
    }
    . . . . .
    // Changes visual status of Radiobutton in the View.
    private void setRadiobuttonVisualStatus(UserAuthorizationLevel userAuthorizationLevel)
    {
        if (userAuthorizationLevel == UserAuthorizationLevel.Manufacturer)
            this.IsVisible = Visibility.Visible;
        else
            this.IsVisible = Visibility.Collapsed;
    }

    // Controls visual status of Radiobutton in the View; the Visibility property
    // of Radiobutton in the View is bound to this property.
    public Visibility IsVisible
    {
        get { return this._isVisible; }
        set { this.SetProperty(ref this._isVisible, value); }
    }
}

我请原谅我在这里做了一个不好的决定:我在模块中控制Radiobutton的可见性状态,而不是动态加载模块本身,因为我的应用程序必须提供更改用户的机会在同一个会话中。棱镜模块在初始化后无法卸载。)现在,回到我们的羊群;我在订阅者端设置了ThreadOption.BackgroundThread,因为发布者在TPL任务中发布事件但在UI线程中没有。我想知道:为什么订阅者根本不对已发布的活动做出反应?我做错了什么?请帮帮我。

2 个答案:

答案 0 :(得分:0)

尚未对此进行测试,但您似乎是在单独的线程上发布该事件。因此,该事件不会自动冒泡到订阅者正在收听的UI线程。

您可以尝试等待任务,然后在任务完成时发布事件,或者您可以尝试在后台线程上订阅事件。

编辑: 我看到了问题。您正在使用共享项目。这不行。 SharedProject不会生成程序集,而是表现为类在引用的程序集中定义并在其中编译。你必须使用PCL。

答案 1 :(得分:0)

此处的问题是在共享项目中定义的事件,而不在类库中定义。

这样,事件被复制到引用项目,实际上存在两个不同的事件(具有相同的名称),一个被订阅,另一个被发布。