Some clarification surrounding class initialization

JasinCole

Well-known member
Joined
Feb 16, 2023
Messages
66
Programming Experience
1-3
I got somewhat of an unusual question. It all started around an issue with the Rider plugin for avalonia. I'll try to explain as best I can

In my avalonia xaml code I use the following
C#:
<Design.DataContext>
    <vm:HomePageViewModel/>
</Design.DataContext>

This was causing the plugin to crash because it was essentially telling me, I had no default constructor. Creating a default constructor solved the plugin issue. But that got me thinking about some other issues.

This code now resides in my VM
C#:
private readonly SageDbContext _ctx = null!;

    public HomePageViewModel()
    {
        
    }
    
    public HomePageViewModel(SageDbContext ctx)
    {
     _ctx = ctx;
     InitializeAsync().SafeFireAndForget();
    }

The question I have is why did rider suggest to use a null supression on the _ctx initialization(there were other options)? How does this now effect my other code that uses DI?

I guess what I am trying to understand is what are the downsides of code like this? I could have
private readonly SageDbContext? _ctx
But then I would have had to check for null in all my methods or get more compiler warnings. (trying to weed these out)
Is there anytime that this _ctx would be null if object initialization is done via DI?
Is it bad to have a default constructor if it is never used?
Is there a better way to handle this without going through all the headache of checking for null everywhere?
 
You shouldn't even have this:
XML:
<Design.DataContext>
    <vm:HomePageViewModel/>
</Design.DataContext>
If your class has required values to be initialized. Constructors are the way to enforce those required values. As far as I know, there's no way to pass in the XAML what those values should be. By creating a default constructor with no required values, you are now saying that your class doesn't need required values.

Anyway, consider the Null Object design pattern where you can construct a dummy object to stand in for your "uninitialized" _ctx.
 
You shouldn't even have this:

Correct, I do not require it, but I am curious why you say it's not needed.

I can't recall where I found that at, but rider is brain dead if you don't tell it where to find the context of reflection bindings. Those 3 lines are for the sake of the compiler to shutup about an unknown path when using reflection bindings in xaml.

By creating a default constructor with no required values, you are now saying that your class doesn't need required values.

My assumption was correct then, it's bad design
 
Correct, I do not require it, but I am curious why you say it's not needed.

Because by using that in the XAML, you are saying that the view model behind that UI can be constructed using a default constructor.

You can probably play some binding tricks like in some of the SO answers here:
 

Latest posts

Back
Top Bottom