Reputation: 763
I have an application that serves as both "Client" and "Server" to showcase single communication between these. Inside this application, I have a class called "ClientConnectionService" that holds all the methods for the client-side communication:
public class ClientConnectionService : ConnectionModelBase
{
public string Connect()
{
//Some code here
}
public void OnDataReceived()
{
//Some code here
}
public virtual void WaitForData()
{
//Some code here
}
public void SendMessage(string msg)
{
//Some code here
}
public string Disconnect()
{
//Some code here
}
}
Using MVVM, I made a View and a ViewModel for 2 UserControls: ConnectToServerView/ViewModel and ViewUserView/ViewModel.
public partial class ViewUserView : UserControl
{
private ViewUserViewModel viewModel = new ViewUserViewModel();
public ViewUserView()
{
DataContext = viewModel;
}
}
public class ViewUserViewModel : ViewModelBase
{
private ClientConnectionService clientConnectionService
= new ClientConnectionService();
public ViewUserViewModel()
{
}
}
The other View/ViewModel is basically the same as the ones above, so I'll skip the code for that one (for simplicity purposes).
I KNOW this is wrong, as when trying to access the socket for the "Client" inside the ViewUserViewModel, it appears null (because I did not call the "Connect" method, where I actually set this "client socket"), because this instance of the "ClientConnectService" is not the same instance as the one I called in the "ConnectToServerViewModel".
TL;DR I have 2 viewModels with 2 different instances of a class, and I need to share that instance (of the class) between these (and possibly more) viewModels.
My question is: Is Dependency Injection the way to go? ('Cause I've been trying to implement it, but the interface is always null, so I think I'm missing something), or is there a way to make this "ClientConnectionService" class "sharable" between all my ViewModel instances (or the ones that need them, at least)
Upvotes: 2
Views: 143
Reputation: 19640
Dependency injection would require you to resolve your view models from a container. This means that you will need to have some way to resolve view models per view instead of instantiating them. It is better done when using some ready-made MVVM frameworks like Caliburn Micro.
What you are really looking for is a Singleton pattern. Although IoC is nice, you might not want to do it just to have one singleton in your application.
If you really want to look at using IoC and DI in your app, you can check Caliburn Micro or ReactiveUI. Both use some simple service locators (check here and here) that is used to resolve VMs and dependencies. I also made a sample adaptor for Autofac to be used with RxUI 6.
Upvotes: 1
Reputation: 763
Following up with what @Alexey Zimarev answered, here is my version of a Singleton implementation:
public class ClientConnectionService : ConnectionModelBase
{
private static readonly ClientConnectionService instance
= new ClientConnectionService();
private ClientConnectionService() { }
public static ClientConnectionService getClientConnectionService()
{
return instance;
}
public string Connect(string ipAddress, int portNumber)
{
//Some code
}
//More code below, just omitted.
}
Then, just calling it in any viewModel as:
public class ConnectToServerViewModel : ViewModelBase
{
#region Singletons
private ClientConnectionService clientConnectionService =
ClientConnectionService.getClientConnectionService();
#endregion
//Code omitted for simplicity purposes
}
This solved the issue I had, but I would really want to see if there is another way to do this (Specially with DI, since I'm really interested in the subject).
Thanks a lot to everyone who contributed.
Upvotes: 1