C
C#2mo 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 》AOC 2024 🎅🏼
I dont see where you add the services to a serviceprovider and then build the provider?
Shock
ShockOP2mo 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 》AOC 2024 🎅🏼
in the MainViewModel, is CustomWrapper null?
Shock
ShockOP2mo ago
Well that's weird - it is null
🎅🏼Async-Void 》AOC 2024 🎅🏼
that tells me the DI isnt setup correctly
Shock
ShockOP2mo 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 》AOC 2024 🎅🏼
so where does customWrapper show null?
Shock
ShockOP2mo 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
Shock
ShockOP2mo 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?