Caliburn.Micro EventAggregator

2019-07-06 17:02发布

问题:

Apologise if this a really stupid question but I'm just getting started with caliburn.micro and I'm struggling with getting the eventAggregator, nothing seems to be subscribing...

I'm not sure whether the problem is with the view model or the bootstrapper. Here is the viewmodel:

class MainWindowViewModel : Screen
{
    private readonly IEventAggregator _eventAggregator;

    public MainWindowViewModel(IEventAggregator eventAggregator)
    {
        _eventAggregator = eventAggregator;
        _eventAggregator.Subscribe(this);
    }

    public void SayHello()
    {
        _eventAggregator.Publish("Hello World!");
    }

    public void Handle(string message)
    {
        MessageBox.Show(message);
    }
}

Bootstrapper:

class AppBootstrapper : Bootstrapper<MainWindowViewModel>
{
      public static readonly Container ContainerInstance = new Container();

    protected override void Configure()
    {
        ContainerInstance.Register<IWindowManager, WindowManager>();
        ContainerInstance.RegisterSingle<IEventAggregator,EventAggregator>();
        ContainerInstance.Register<MainWindowViewModel, MainWindowViewModel>();

        ContainerInstance.Verify();
    }

    protected override IEnumerable<object> GetAllInstances(Type service)
    {
        return ContainerInstance.GetAllInstances(service);
    }

    protected override object GetInstance(System.Type service, string key)
    {
        return ContainerInstance.GetInstance(service);
    }

     protected override void BuildUp(object instance)
    {
        ContainerInstance.InjectProperties(instance);
    }
}

Any ideas what I'm missing, I feel I must not be linking somewhere...

I am using SimpleInjector as the IOC Container

EDIT:

It seems like a very simple case of I didn't know what I was doing. RTFM.

Implementing IHandle does work. It seems to get called twice the first time the type is handled though. I'll do some investigating as to why.

回答1:

It sounds like you've already arrived at a solution of sorts.

I believe it should work provided you implement an IHandle<T> interface using a type compatible with the even you're publishing. E.g:

class MainWindowViewModel : Screen, IHandle<string>
{ 
    //... Your Code

    public void Handle(string myEventstring)
    {
        // Do Something.
    }
}

If at all helpful, when I use the EventAggregator, I tend to create a static EventAggregator instance (from a small helper class) which I use in any ViewModels that require it - it may help in cases where you've actually initialised the EventAggregator multiple times by accident (might be the cause of your double event).

I also sometimes create small helper classes to wrap up event information. E.g:

public sealed class DownloadFinishedEvent
{
    public readonly string EventText = "Download Completed";

    // Additional Download Info Here.

    public override string ToString()
    {
        return this.EventText;
    }
}


回答2:

The caliburn micro doc example shows, that the subscriber has to implement the IHandle interface. I think that's the problem.