Notify one of hundreds of viewmodels with MVVM Light messenger Assume a viewmodel for hosting a collection of item viewmodels. There can be some hundreds of items in the collection. The items are part of the business model and have an id and a name. The name for a specific item can be changed somewhere in the application and the viewmodel in the collection needs to be notified to refresh the property:

public interface IItem
{
    Guid Id { get; }
    string Name { get; }
}

public class ItemModel : ViewModelBase
{
    private IItem _item;

    public ItemModel(IItem item)
    {
        _item = item;
    }

    public void Refresh()
    {
        RaisePropertyChanged(nameof(Name));
    }

    public Guid Id { get { return _item.Id; } }

    public string Name { get { return _item.Name; } }

    private bool _isSelected;

    public bool IsSelected
    {
        get { return _isSelected; }
        set { Set(ref _isSelected, value); }
    }
}

public class ListModel : ViewModelBase
{
    public ListModel(IEnumerable&lt;ItemModel&gt; items)
    {
        Items = new ObservableCollection&lt;ItemModel&gt;(items);
    }

    public ObservableCollection&lt;ItemModel&gt; Items { get; }
}


I have tried the following solutions, but i am not sure what the best one is:


register every item at creation and let the messenger always notify them all

public class ItemModel : ViewModelBase
{           
    public ItemModel(IItem item)
    {
        _item = item;

        MessengerInstance.Register&lt;NotificationMessage&gt;(this, (msg) =&gt; {
            if (msg.Notification == "REFRESH" &amp;&amp; IsSelected)
            {
                Refresh();
            }
        });
    }

    [...]

register / unregister messenger on selection, so there will be only one viewmodel be registered 

public class ItemModel : ViewModelBase
{
    [...]

    public bool IsSelected
    {
        get { return _isSelected; }
        set
        {
            if (Set(ref _isSelected, value))
            {
                if (value)
                {
                    MessengerInstance.Register&lt;NotificationMessage&gt;(this, (msg) =&gt; {
                        if (msg.Notification == "REFRESH")
                        {
                            Refresh();
                        }
                    });
                }
                else
                {
                    MessengerInstance.Unregister&lt;NotificationMessage&gt;(this);
                }
            };
        }
    }
}

register the hostig viewmodel and iterate over the items, so there wil be only one registration too

    public ListModel(IEnumerable&lt;ItemModel&gt; items)
    {
        [...]

        MessengerInstance.Register&lt;NotificationMessage&lt;Guid&gt;&gt;(this, (msg) =&gt; {
            if (msg.Notification == "REFRESH")
            {
                var item = Items.Single&lt;ItemModel&gt;(x =&gt; x.IsSelected);
                item.Refresh();
            }
        });
    }



which solution would you prefer? register and unregister on every selection or having hundereds of viewmodels registered to the messenger or itereate the items yourself? maybe there is also a better solution?
It should be up to that ViewModel how it handles messages and if it wants to ignore them or act on them.  So that rules out option 3.  That just leaves option 1 and 2.  Option 2 will work but as a developer I wouldn't normally think that setting a property of IsSelected to have side effects and we all know side effects are bad.  I just think it adds a bit more in the maintenance that doesn't need.   I typically just do option 1 and I typically have one method in a class that handles all the registrations for the messages and what they should do.  Just makes maintenance easier if you have a message issue you know where they are all getting registered at.  

And since this is CodeReview and all code is subject to review I would recommend you get rid of "magic" strings and make a class that holds them all.  Something like

public static class Messages
{
    public const string Refresh = "REFRESH";
}