Click here to Skip to main content
15,881,173 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
So this is going to sound silly, but I'm lost as to the correct way to do this. Its basically an excercise to figure it out.

Say I have a simple console app that connects to a WCF endpoint and sends text messages over a simple SendMessage(string text) call.

I want to write an MVVM UI that basically renders these as they come in. So my initial thinking is create a thread in the ViewModel that hosts the WCF service, somehow traps the events from the service, updates a property, and then that gets bound to the UI layer.

So I guess my question is; how do I do this? To be more specific;
1. Is it Model or ViewModel that hosts the WCF service?
2. How do I pass the events from the service? Do I have the service fire events?

Is there an example of something similar that I can look at somewhere that might make sense? An MVVM chat client/server that uses WCF or something?
Posted

Since I needed to solve a similar conundrum I gave it some though and this is what I came up: you can do this with binding instead of an event, I would use a service to get the messages, this is different than your WCF service, a service in MVVM is a class that does things for the ViewModel, this way the ViewModel doesn’t need to know how the messages get to it, they just do, lets’ see some code:

The WCF service:
public class MessagesWFCService : IMessagesWFCService
    {
        public void SendMessage(string message)
        {
            MessageService.Instance.AddMessage(message);
        }
    }


The service:
public interface IMessageService
    {
        void AddMessage(string message);
    }

    public class MessageService : IMessageService
    {        
        private static MessageService _Instance = null;
        
        private MessageViewModel _MessageViewModel = null;
        
        private ServiceHost _ServiceHost = null;
        public MessageService()
        {
            _Instance = this;
            _ServiceHost = new ServiceHost(typeof(MessagesWFCService));            
        }
        public void AddMessage(string message)
        {
            _MessageViewModel.Messages.Add(message);
        }
        public void Close()
        {
            _ServiceHost.Close();
        }
        public static MessageService Instance
        {
            get
            {
                return _Instance;
            }
            set
            {
                if(_Instance != value)
                    _Instance = value;
            }
        }
        public MessageViewModel MessageViewModel
        {
            get
            {
                return _MessageViewModel;
            }
            set
            {
                if(_MessageViewModel != value)
                    _MessageViewModel = value;
            }
        }
        public void Open()
        {
            _ServiceHost.Open();
        }
    }


The ViewModel
public class MessageViewModel : INotifyPropertyChanged
    {        
        public event PropertyChangedEventHandler PropertyChanged;

        private ObservableCollection<string> _Messages = null;
                
        private IMessageService _MessageService = null;

        public MessageViewModel()
        {
            _MessageService = new MessageService();
            _MessageService.MessageViewModel = this;
            _MessageService.Open();
        }
        public ObservableCollection<string> Messages
        {
            get
            {
                return _Messages;
            }
            set
            {
                if(_Messages != value)
                {
                    _Messages = value;
                    PropertyChangedEventHandler eventHandler = PropertyChanged;
                    if(eventHandler != null)
                        eventHandler(this, new PropertyChangedEventArgs("Messages"));
                }
            }
        }
    }


Of course you’ll need to set the view’s DataContext to the ViewModel and bind the ItemsSource property of the control to the ViewModel’s Messages property.

If you are using Prism or Unity you should use the Container to resolve the MessageService instead of creating the instance directly.

Take a look, keep in mind that I haven’t tested this yet, but I will, and I think it can give you some guidance.
 
Share this answer
 
that makes less sense..

you're suggesting:
client <--> WCF on IIS <--> MVVM UI

That's doable, but requires IIS. I want to do the same thing, essentially, but host it over ServiceHost inside the app itself. I.E. the app IS the service host, so that clients connect to it directly.
 
Share this answer
 
xeroxducati wrote:
Is it Model or ViewModel that hosts the WCF service?


Neither hosts the service. IIS does.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900