C
C#3mo ago
Shock

Dependency Injection returning null value

I've created a WPF application that uses DI for the View/Viewmodel. I'm attempting to create a CS file to deal with the program logic that uses a dependency injected Service Wrapper. However, whenever I call the Service in the new class, the value is returning as null. I've included a shortened version below that hopefully gets the point across.
MyService.CS
public class CustomWrapper : ICustomWrapper
{
public Connect () {}
public Disconnect () {}
}
public interface ICustomWrapper
{
public Connect(string);
public Disconnect();
}
public class CustomWrapper : ICustomWrapper
{
public Connect () {}
public Disconnect () {}
}
public interface ICustomWrapper
{
public Connect(string);
public Disconnect();
}
MainWindow.xaml.cs
public partial class MainWindow : Window
{
public static string radioParse {get; set;}
private readonly ICustomWrapper _customWrapper;
public MainWindow (ICustomWrapper customWrapper)
{
_customWrapper = customWrapper;
InitializeComponent();
}

public void Proceed_Click(object sender, RoutedEventArgs e)
{
var radioButton = Session.Children.OfType<RadioButton>()
.FirstOrDefault(r=> r.IsChecked.HasValue && r.IsChecked.Value);
if (radioButton == null)
MessageBox.Show("Select an Option");
else if (radioButton != null)
{
radioParse = "A"
SelectValue();
}
}
public void SelectValue();
{
_customWrapper.Connect(radioParse)
}
public partial class MainWindow : Window
{
public static string radioParse {get; set;}
private readonly ICustomWrapper _customWrapper;
public MainWindow (ICustomWrapper customWrapper)
{
_customWrapper = customWrapper;
InitializeComponent();
}

public void Proceed_Click(object sender, RoutedEventArgs e)
{
var radioButton = Session.Children.OfType<RadioButton>()
.FirstOrDefault(r=> r.IsChecked.HasValue && r.IsChecked.Value);
if (radioButton == null)
MessageBox.Show("Select an Option");
else if (radioButton != null)
{
radioParse = "A"
SelectValue();
}
}
public void SelectValue();
{
_customWrapper.Connect(radioParse)
}
MainWindow.Xaml
<StackPanel>
<Button Content = "Proceed"
Command = "{Binding Path=NavigateHomeCommand}
Click = "Proceed_Click"/>
</StackPanel>
<StackPanel>
<Button Content = "Proceed"
Command = "{Binding Path=NavigateHomeCommand}
Click = "Proceed_Click"/>
</StackPanel>
MainViewModel.cs
private ICustomWrapper _customWrapper;
public RelayCommand NavigateHomeCommand
public MainViewModel(INavigationService navigationService, ICustomWrapper customWrapper)
{
NavigateHomeCommand = new RelayCommand (o=> {Navigation.NavigateTo<HomeViewModel>(); } o=> true;
}
private ICustomWrapper _customWrapper;
public RelayCommand NavigateHomeCommand
public MainViewModel(INavigationService navigationService, ICustomWrapper customWrapper)
{
NavigateHomeCommand = new RelayCommand (o=> {Navigation.NavigateTo<HomeViewModel>(); } o=> true;
}
App.xaml
<DataTemplate DataType = "{x:Type TypeName=viewModel:HomeViewModel}">
<view:HomeView/>
</DataTemplate>
<DataTemplate DataType = "{x:Type TypeName=viewModel:HomeViewModel}">
<view:HomeView/>
</DataTemplate>
App.Xaml.Cs
public partial class App : Application
{
private readonly IServiceProvider _serviceProvider;
private readonly IService Collection services = new ServiceCollection();
{
public App
{
services = new ServiceCollection();
services.AddSingleton<MainWindow>(s =>
{
var window = new mainWindow(s.GetRequiredService<ICustomWrapper>());
window.DataContext = s.GetRequiredService<MainViewModel>();
return window;
});
services.AddSingleton<MainViewModel>();
services.AddSingleton<HomeViewModel>();
services.AddSingleTon<INavigationService, navigationService>();
services.AddSingleTon<ICustomWrapper, customWrapper>();
services.AddSingleton<Func<Type, ViewModelBase>>(serviceProvider => viewModelType => (ViewModelBase)serviceProvider.GetRequiredService(viewModelType));
_serviceProvider = services.BuildServiceProvider();
}

protected override void ONstartup(StartupEventArgs e)
{
MainWindow = _serviceProvider.GetRequiredService<MainWindow>();
MainWindow.Show();
base.OnStartup(e);
}
public partial class App : Application
{
private readonly IServiceProvider _serviceProvider;
private readonly IService Collection services = new ServiceCollection();
{
public App
{
services = new ServiceCollection();
services.AddSingleton<MainWindow>(s =>
{
var window = new mainWindow(s.GetRequiredService<ICustomWrapper>());
window.DataContext = s.GetRequiredService<MainViewModel>();
return window;
});
services.AddSingleton<MainViewModel>();
services.AddSingleton<HomeViewModel>();
services.AddSingleTon<INavigationService, navigationService>();
services.AddSingleTon<ICustomWrapper, customWrapper>();
services.AddSingleton<Func<Type, ViewModelBase>>(serviceProvider => viewModelType => (ViewModelBase)serviceProvider.GetRequiredService(viewModelType));
_serviceProvider = services.BuildServiceProvider();
}

protected override void ONstartup(StartupEventArgs e)
{
MainWindow = _serviceProvider.GetRequiredService<MainWindow>();
MainWindow.Show();
base.OnStartup(e);
}
There is a lot more there, but they are all instantiated as singleton. HomeView.xaml.Cs
public partial HomeView : UserControl
{
private readonly ICustomWrapper _customWrapper;
private readonly MainWindow mainWindow;

public HomeView(ICustomWrapper customWrapper, MainWindow mainWindow)
{
_mainWindow = mainWindow
customWrapper = customWrapper
}
private HomeView()
{
InitializeComponent();
}
private void Button1_Click(object sender, RoutedEventArgs e)
{
Logic _logic = new Logic(_customWrapper, _mainWindow);
_logic.Select();
}
}
public partial HomeView : UserControl
{
private readonly ICustomWrapper _customWrapper;
private readonly MainWindow mainWindow;

public HomeView(ICustomWrapper customWrapper, MainWindow mainWindow)
{
_mainWindow = mainWindow
customWrapper = customWrapper
}
private HomeView()
{
InitializeComponent();
}
private void Button1_Click(object sender, RoutedEventArgs e)
{
Logic _logic = new Logic(_customWrapper, _mainWindow);
_logic.Select();
}
}
And finally. Logic.CS
public class Logic
{
private readonly ICustomWrapper _customWrapper;
private readonly MainWindow _mainWindow
public string connectLetter = Mainwindow.radioParse;

public Logic(ICustomWrapper customWrapper, MainWindow mainWindow)
{
_MainWindow = mainWindow;
_customWrapper = customWrapper;
}
public void Select()
{
_customWrapper.Disconnect();
]
public class Logic
{
private readonly ICustomWrapper _customWrapper;
private readonly MainWindow _mainWindow
public string connectLetter = Mainwindow.radioParse;

public Logic(ICustomWrapper customWrapper, MainWindow mainWindow)
{
_MainWindow = mainWindow;
_customWrapper = customWrapper;
}
public void Select()
{
_customWrapper.Disconnect();
]
10 Replies
Async-Void 》
Async-Void 》3mo ago
I dont see where you add the services to a serviceprovider and then build the provider?
Shock
ShockOP3mo ago
I skipped adding that since I was copying this from a computer without discord access let me edit that in from what it really looks like The DI was working as expected (allowing me to change view/viewmodels with the Navigate commands) before I tried to add Logic.CS into the mix
Async-Void 》
Async-Void 》3mo ago
in the MainViewModel, is CustomWrapper null?
Shock
ShockOP3mo ago
Well that's weird - it is null
Async-Void 》
Async-Void 》3mo ago
that tells me the DI isnt setup correctly
Shock
ShockOP3mo ago
Let me see if it returns null before I change ViewModels When I breakpoint NavigateHomeCommand, customWrapper shows Namespace.Services.CustomWrapper so it's set then
Async-Void 》
Async-Void 》3mo ago
so where does customWrapper show null?
Shock
ShockOP3mo ago
I think I just figured it out I shortened the example for the 2000/4000 character limit, but in actuality the proceed button goes to HomeView MOdel which I then select the next ViewModel which we can call AwayViewModel But I don't have the DI setup on the first ViewModel I change to so I think it's nulling out since that ViewModel isn't setup with DI but the other one is
Async-Void 》
Async-Void 》3mo ago
ahhhhh
Shock
ShockOP3mo ago
So the MainViewModel files above are actually AwayViewModel in my actual program But it makes sense since I don't have that setup I will jump immediately to AwayViewModel and see if it nulls but I think it should work Ahh yes that's my problem thank you! I set up the DI on the MainViewModel, but not the subsequent Away/Home view models So when I swithc VM, it's dropping the MainViewModel as expected but I just set it up on the other 2 and it'll carry

Did you find this page helpful?