Here's a pattern that might work for you.
EDIT: Sample code is located here -> https://github.com/kiliman/MvxEventsSample
Basically, create an inner class in your service class named Events
. This will have properties for each event that is published by your service. Then in your view model, you create an instance of this Events class and add whatever handlers you want. This way, you have a nice descriptive class showing what events are available, but still uses MvxMessenger
to ensure weak references.
public interface IMyService
{
void Logon();
void DoSomething();
}
public class MyService : IMyService
{
private readonly IMvxMessenger _messenger;
public MyService(IMvxMessenger messenger)
{
_messenger = messenger;
}
public void Logon()
{
_messenger.Publish(new LogonChangedMessage(this));
}
public void DoSomething()
{
_messenger.Publish(new AnotherEventMessage(this, string.Format("Do Something at {0}", DateTime.Now)));
}
// Events class defines all possible events as properties
// Notice that we only need setters
// We also store the subscription tokens
public class Events
{
private readonly IMvxMessenger _messenger;
public Events(IMvxMessenger messenger)
{
_messenger = messenger;
}
private MvxSubscriptionToken _logonChangedToken;
public Action<LogonChangedMessage> OnLogonChanged
{
set { _logonChangedToken = _messenger.Subscribe(value); }
}
private MvxSubscriptionToken _anotherEventToken;
public Action<AnotherEventMessage> OnAnotherEvent
{
set { _anotherEventToken = _messenger.Subscribe(value); }
}
}
public class LogonChangedMessage : MvxMessage
{
public LogonChangedMessage(object sender) : base(sender)
{
}
}
public class AnotherEventMessage : MvxMessage
{
public AnotherEventMessage(object sender, string text) : base(sender)
{
Text = text;
}
public string Text { get; set; }
}
}
And here's how you would use it in the view model. Notice how I create an instance of MyService.Events
, and then use lambda expressions to setup the event handlers.
public class FirstViewModel : MvxViewModel
{
private readonly IMyService _myService;
private readonly MyService.Events _events;
private int _counter = 0;
public FirstViewModel(IMyService myService, IMvxMessenger messenger)
{
_myService = myService;
// Initialize event handlers using lambda expressions
_events = new MyService.Events(messenger)
{
OnLogonChanged = message =>
{
Hello = "OnLogonChanged: " + (++_counter);
Mvx.Trace("OnLogonChanged");
},
OnAnotherEvent = message =>
{
Hello = message.Text;
Mvx.Trace("OnAnotherEvent");
}
};
}
private string _hello;
public string Hello
{
get { return _hello; }
set { _hello = value; RaisePropertyChanged(() => Hello); }
}
private MvxCommand _logonCommand;
public ICommand LogonCommand
{
get
{
_logonCommand = _logonCommand ?? new MvxCommand(_myService.Logon);
return _logonCommand;
}
}
private MvxCommand _doSomethingCommand;
public ICommand DoSomethingCommand
{
get
{
_doSomethingCommand = _doSomethingCommand ?? new MvxCommand(_myService.DoSomething);
return _doSomethingCommand;
}
}
}