Archive for the ‘VB.NET’ Category.

LINQ to SQL Gotcha #1: Unexpected LoadWith Behaviour

By default, LINQ to SQL uses deferred loading. When you want to eager load an entity’s associated data you need to set DataLoadOptions using the LoadOptions property on the DataContext. If you have a one-to-many relationship between Users and Articles you can force LINQ to SQL to eager load Articles with Users like this:

Using testData As New TestDataContext
 
    ' Log SQL queries to the console
    testData.Log = Console.Out
 
    ' Set LoadOptions
    Dim options As New DataLoadOptions
    options.LoadWith(Function(user As User) user.Articles)
    testData.LoadOptions = options
 
    ' Load users with their articles
    Dim users = testData.Users.ToList
    For Each user In users
        Dim articles = user.Articles.ToList
    Next
 
End Using

This will generate a single SELECT statement with a JOIN on the Articles table. The same goes for for one-to-one relationships. You can also use LoadWith as many times as you want. For one-to-one relationships and no more than a single one-to-many relationship this will still generate one query with JOINs to all the LoadWith tables. However, if you want to eager load multiple one-to-many relationships you will get into a select N + 1 situation (or worse). For example, this code eager loads Articles and UserGroups with each User entity:

Using testData As New TestDataContext
 
    ' Log SQL queries to the console
    testData.Log = Console.Out
 
    ' Set LoadOptions
    Dim options As New DataLoadOptions
    options.LoadWith(Function(user As User) user.Articles)
    options.LoadWith(Function(user As User) user.UserGroups)
    testData.LoadOptions = options
 
    ' Load users with their articles
    Dim users = testData.Users.ToList
    For Each user In users
        Dim articles = user.Articles.ToList
        Dim userGroups = user.UserGroups.ToList
    Next
 
End Using

Technically, the behaviour here is correct. It will successfully eager load both the Articles and UserGroups collections for each User, but it will not do it in a single query. When I ran this I got one query that fetched the Users and Articles like last time, but then a separate SELECT for each UserGroup rather than another JOIN. Even though this won’t alter the behaviour of the code, it will definitely make a major impact on performance, especially if there are a lot of users in the database.

Scott Guthrie confirmed this behaviour in a post on David Hayden’s blog. This is what he said:

In the case of a 1:n associations, LINQ to SQL only supports joining-in one 1:n association per query.

Lame.

High performance database rollback in automated tests with SQL Server

A couple months ago I wrote this article explaining why I think it is reasonable for unit tests to hit a real database. Subsequently, I wrote a follow up article describing some techniques for rolling back your database to its original state after each test. In that article I found that just using simple transactions did not solve the problem because you need access to all database connections being used, and they all have to be rolled back. I have since found a way around this problem using distributed transactions.

With the Microsoft Distributed Transaction Coordinator (MSDTC) the activity over multiple connections can be lumped into a single transaction using the TransactionScope class. MSDTC needs to be running for this to work, but since this is just for unit tests it doesn’t need to be enabled on your production environment.

In order to use the TransactionScope class your project will need a reference to System.Transactions. Here’s a sample unit test using MSTest and Entity Framework where the database is altered with multiple connections within a transaction and then the changes are rolled back:

Imports System.Transactions
Imports System
Imports System.Text
Imports System.Collections.Generic
Imports Microsoft.VisualStudio.TestTools.UnitTesting
 
<TestClass()> _
Public Class UnitTestSample
 
    <TestMethod()> _
    Public Sub ProofOfConceptTest()
        Using New TransactionScope
            Dim conn1 As New DataTestEntities
            Dim conn2 As New DataTestEntities
 
            Dim row1 As New Users With {.userName = "user1", .password = "pass"}
            Dim row2 As New Users With {.userName = "user2", .password = "pass"}
 
            conn1.AddToUsers(row1)
            conn2.AddToUsers(row2)
 
            conn1.SaveChanges()
            conn2.SaveChanges()
 
            Dim conn3 As New DataTestEntities
            Assert.AreEqual(conn3.Users.Count, 6)
        End Using
    End Sub
 
End Class

Alternatively, if you want every test method inside a test class to be within its own TransactionScope without adding a Using block to every single test, you can use the initialization and cleanup methods like this:

Imports System.Transactions
Imports System
Imports System.Text
Imports System.Collections.Generic
Imports Microsoft.VisualStudio.TestTools.UnitTesting
 
<TestClass()> _
Public Class UnitTestSample
 
    Private _transaction As TransactionScope
 
    <TestInitialize()> _
    Public Sub Setup()
        _transaction = New TransactionScope
    End Sub
 
    <TestCleanup()> _
    Public Sub TearDown()
        _transaction.Dispose()
    End Sub
 
    <TestMethod()> _
    Public Sub ProofOfConceptTest()
        Dim conn1 As New DataTestEntities
        Dim conn2 As New DataTestEntities
 
        Dim row1 As New Users With {.userName = "user1", .password = "pass"}
        Dim row2 As New Users With {.userName = "user2", .password = "pass"}
 
        conn1.AddToUsers(row1)
        conn2.AddToUsers(row2)
 
        conn1.SaveChanges()
        conn2.SaveChanges()
 
        Dim conn3 As New DataTestEntities
        Assert.AreEqual(conn3.Users.Count, 6)
    End Sub
 
End Class

As long as the use of MSDTC is an option, I have found this method to be far better than any of those described in the last article. It guarantees that the state or your database is maintained and is extremely fast (at least on small amounts of data).

Finding all validation errors on an IDataErrorInfo object

WPF data binding has built in support for IDataErrorInfo, so it is easy to display a validation error when a property has invalid data. However, sometimes we need to manually find all the validation errors on an object. A perfect example of this is when trying to save data. Often you will want to verify that there are no validation errors before allowing the save operation to proceed. Using the MVVM pattern it would be ideal to determine whether there are any errors purely within your model view. The default behavior of IDataErrorInfo does not give a collection of all current errors. Instead, it will just tell you if a given property has an error (ie: using IDataErrorInfo.Item), so all we have to do to find all the errors is enumerate through each property on the class and call the Item property with that property name as the argument. The GetValidationErrors function below does exactly that:

Option Strict On
 
Imports System.ComponentModel
 
Public Class ValidationHelper
 
    ''' <summary>
    ''' Checks for errors in <c>validatable</c> and returns all the errors found.
    ''' </summary>
    Public Shared Function GetValidationErrors(ByVal validatable As IDataErrorInfo) As IEnumerable(Of DataError)
 
        Dim errors As New List(Of DataError)
 
        ' Iterate through every property in the class
        For Each prop In validatable.GetType.GetProperties
 
            ' If the property has an error, then add it to the list
            Dim errorMessage = validatable(prop.Name)
            If errorMessage IsNot Nothing Then
                errors.Add(New DataError(prop.Name, errorMessage))
            End If
 
        Next
 
        Return errors
 
    End Function
 
    ''' <summary>
    ''' Represents a single error.  It's a propertyName, errorMessage pair
    ''' </summary>
    Public Class DataError
 
        Private _propertyName As String
        Private _errorMessage As String
 
        Public Sub New(ByVal propertyName As String, ByVal errorMessage As String)
            _propertyName = propertyName
            _errorMessage = errorMessage
        End Sub
 
        ''' <summary>
        ''' The name of the property that has the error.
        ''' </summary>
        Public ReadOnly Property PropertyName() As String
            Get
                Return _propertyName
            End Get
        End Property
 
        ''' <summary>
        ''' A description of the property's error.
        ''' </summary>
        Public ReadOnly Property ErrorMessage() As String
            Get
                Return _errorMessage
            End Get
        End Property
 
    End Class
 
End Class

Specifying expected DataContext type in WPF

Josh Smith just made a blog post about XAML DataContext comments when using the MVVM pattern. He makes a great point, which is that in many cases it is not immediately obvious what the DataContext of a view is intended to be. A simple comment as Josh suggests will go a long way, but the downside is that comments create a maintainability issue. If you rename a model view, or refactor code so that a page, window or user control expects a different DataContext you also need to update the comment. Here’s an example:

<!-- DataContext = SampleModelView -->
<UserControl x:Class="SampleUserControl"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Width="300" Height="300">
    <Grid>
 
    </Grid>
</UserControl>

But now what if I change my mind and decide that instead of SampleModelView, this UserControl will have AlternateModelView as its DataContext? If I forget to update the comment then it is now a source of misinformation. What I would really like to do is somehow specify the expected data context type for a given UI element, so I created an attached property called ExpectedDataContextType. When the element is loaded, it will fail at runtime if the DataContext is not of the desired type. It looks like this:

<UserControl x:Class="TestControl"
    xmlns:local="clr-namespace:ExpectedDataContextType"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Width="300" Height="300"
    local:DataContextHelper.ExpectedDataContextType="{x:Type local:TestModelView}">
    <Grid>
        <TextBlock>Hello</TextBlock>
    </Grid>
</UserControl>

The code is extremely simple. It just attaches a handler to the Loaded event and then checks the type. When the types do not match up it gives you a warning via a message box if you are debugging. I chose not to throw an exception because the exception gets covered up and just ends up as a tiny message on Visual Studio immediate window. When I am debugging and a control has the wrong DataContext I want to make sure I find out about it, hence the message box. You can always replace the message box code with something else though.

Option Strict On
 
Public Class DataContextHelper
 
    Public Shared Function GetExpectedDataContextType(ByVal element As DependencyObject) As Type
        If element Is Nothing Then
            Throw New ArgumentNullException("element")
        End If
 
        Return DirectCast(element.GetValue(ExpectedDataContextTypeProperty), Type)
    End Function
 
    Public Shared Sub SetExpectedDataContextType(ByVal element As DependencyObject, ByVal value As Type)
        If element Is Nothing Then
            Throw New ArgumentNullException("element")
        End If
 
        element.SetValue(ExpectedDataContextTypeProperty, value)
    End Sub
 
    Public Shared ReadOnly ExpectedDataContextTypeProperty As  _
                           DependencyProperty = DependencyProperty.RegisterAttached("ExpectedDataContextType", _
                           GetType(Type), GetType(DataContextHelper), _
                           New FrameworkPropertyMetadata(Nothing, AddressOf OnExpectedDataContextTypeChanged))
 
    Private Shared Sub OnExpectedDataContextTypeChanged(ByVal obj As DependencyObject, ByVal args As DependencyPropertyChangedEventArgs)
        Dim element = DirectCast(obj, FrameworkElement)
        AddHandler element.Loaded, AddressOf OnElementLoaded
    End Sub
 
    Private Shared Sub OnElementLoaded(ByVal sender As Object, ByVal args As RoutedEventArgs)
        Dim element = DirectCast(sender, FrameworkElement)
 
        RemoveHandler element.Loaded, AddressOf OnElementLoaded
 
        ' Compare the expected type to the actual type
        Dim expectedDataContextType = GetExpectedDataContextType(element)
        Dim actualDataContextType = element.DataContext.GetType
        If expectedDataContextType IsNot actualDataContextType Then
 
#If DEBUG Then
            ' The types don't match and debug mode is on so notify the developer that the element
            ' has the wrong data context
            MessageBox.Show(String.Format("DataContext has type {0}. Expected {1}.", _
                                          actualDataContextType.ToString, _
                                          expectedDataContextType.ToString))
#End If
 
        End If
    End Sub
 
End Class

The end result is that you are still specifying what the type of your DataContext should be, but now it is actually enforced. The best part is that if the you rename your model view without updating the ExpectedDataContextType property you will get a compile error because the type no longer exists. If the type still exists then you have to settle for a runtime error.

Unit testing an Entity Framework DAL part 1: Just hit the database

As almost anyone who tries to unit test a database application will quickly discover, databases present a huge problem for unit testing. Strictly speaking, if you are testing your C# or VB code and you actually hit a real database, then it isn’t really a unit test. It is actually an integration test. However, I have found that it doesn’t really matter what you call it, the end result is that your tests are much more useful if they actually hit a real database. You don’t have to worry about whether the test failed because you screwed up your mock object or if the actual application is buggy and you get better code coverage because even broken SQL will lead to a failed test.

There are several methods that can be used to prevent your unit tests from actually using a real SQL Server database, but they all have their problems:

  • Using an in-memory provider like SQLite

    There is an Entity Framework provider for SQLite that allows you to interact with a database without using a network or even going to your file system. This could certainly increase the execution speed of your unit tests and makes it easy to prevent cross contamination in your tests, but they are still integration tests. The only difference is that you are now testing whether your code works on SQLite, rather than the DBMS that you will actually use in production. The problem is that all database systems have different behaviors and feature sets, so your tests are no longer valid if you use a different DBMS for testing. There is also currently no system in place to automatically generate the SQLite schema from your entity data model, so you will need to find your own way of doing that, or you have to manually maintain a separate SQLite schema. Gross. If you are going to use another provider, it needs to be specially designed to behave exactly like your production database (ie: a mock SQL Server provider) but to my knowledge no such providers exists (if I’m wrong, please let me know!).

  • Mock the Entity Framework ObjectContext

    If all you want to do is read data, then this works well and is easy to implement. Unfortunately, in the vast majority of cases, we also need to write data and that’s where this method gets tricky. Your mock ObjectContext needs to be able to track changes and save them to an in-memory repository. And again, you have to make sure that it behaves exactly like your production database. Because this method often involves either a huge wrapper or major alterations to auto-generated code (which means you also need to make your own generator or you’ll lose maintainability) the mock object itself is extremely complicated, leaving a high likelihood that it will have errors. Since the mock is so complicated one could argue that you are again doing integration tests, not unit tests. But this time instead of testing your code and the database, you are testing your code and the mock ObjectContext. Just like the SQLite example, this is much worse because you are testing whether your code integrates with something you will not use in production. If you are going to do integration tests anyways, then you might as well integrate with the real thing. This method could lead to faster executing tests, but don’t forget that a local SQL Server instance is actually extremely fast and might be just as good.

  • Encapsulate your data access layer and then mock it

    I see this response on message boards all the time. Whenever someone asks how they unit test their data access code someone will respond “You’re doing it wrong, put all of your data access code into a separate module that you can mock”. There are a couple problems with this. First of all, you still need to test the code in the data access layer. If you have a function in your DAL that executes a complicated LINQ to Entites query, then you want to test that query. Without using one of the techniques mentioned above, this requires hitting the database. Secondly, making your client code completely unaware of the data access layer’s implementation leads to some issues. Let’s pretend that my data access layer looks like this:

    Public Interface IUsersModel
     
        Function GetUsers() As IEnumerable(Of Users)
        Sub Save()
     
    End Interface
     
    Public Class UsersModel
        Implements IUsersModel
     
        Private _context As New DataTestEntities
     
        Public Function GetUsers() As IEnumerable(Of Users) Implements IUsersModel.GetUsers
            Return _context.Users
        End Function
     
        Public Sub Save() Implements IUsersModel.Save
            _context.SaveChanges()
        End Sub
     
    End Class

    It’s pretty simple, the code just allows you to get a collection of users and save any changes you make. UsersModel correctly implements the interface using the Entity Framework. Then we also have a controller that accesses the DAL. It looks like this:

    Public Class UsersController
     
        Private _usersModel As IUsersModel
     
        Public Sub New(ByVal usersModel As IUsersModel)
            _usersModel = usersModel
        End Sub
     
        Public Sub ChangeFirstUserNameToFoobar()
            _usersModel.GetUsers().First.userName = "foobar"
            _usersModel.Save()
        End Sub
     
    End Class

    UsersController has a dependency on IUsersModel, so when unit testing the ChangeFirstUserNameToFoobar method, we pass in a mock implementation of IUsersModel, but we cannot simply verify that Save() was called, we also need to know what is going to happen when Save is called. Specifically, we need some way of checking that the first user’s username was changed to “foobar”. This means that a mocking framework like RhinoMocks or Moq will not be sufficient. There must be a fake implementation of IUsersModel that keeps track of the changes that have been made. Now we are getting back into “mock the ObjectContext” territory because that’s basically what we will have done.

There is a definite trend here: each of the above methods is complicated enough that you lose the benefits of isolating your tests from the database. They are all integration tests. In every case you are testing your client code, plus the repository. Since you have to test a repository, it might as well be the real one. Of course, this presents its own challenges. You will want to use a local instance of SQL Server (or whatever DBMS you use) to keep the tests fast (and isolated from other developers) and you will need to roll back changes after each test. In subsequent articles I will look at how to deal with these issues.

Update: I have posted the second article: Unit testing an Enitity Framework DAL part 2: Rolling back the test database

WPF nullable combo box source code

Download the code here: WpfNullableComboBox.zip

A few months ago I wrote this article on making a nullable combo box control in WPF. I had a bunch of requests to see an actual implementation, so here is a sample Visual Studio 2008 project with the source code for the user control. It basically uses the same technique I described in my previous blog post. All the combo box properties (even the obscure ones no one will ever use) are implemented.

Easier PropertyChanged notification with PostSharp

As I described in this previous article raising the PropertyChanged event for classes that implement INotifyPropertyChanged can be a real pain. The biggest problem is that PropertyChangedEventArgs takes the name of the property that changed as a string and as we all know, strings are the root of all evil. Here I will show how to use a simple PostSharp attribute on your properties that need to raise the PropertyChanged event when they are changed so that you don’t manually need to do it and hard code the name of the property as a string. PostSharp is a framework for .NET that allows for aspect oriented programming. You can read all about it at the PostSharp website.

First of all, let’s assume that the classes implementing INotifyPropertyChanged are model view classes in the MVVM pattern. We will use a base class for all model views called BaseModelView that looks like this:

Imports System.ComponentModel
 
''' <summary>
''' Parent class for all model views
''' </summary>
Public Class BaseModelView
    Implements INotifyPropertyChanged
 
    Public Event PropertyChanged( _
        ByVal sender As Object, _
        ByVal e As System.ComponentModel.PropertyChangedEventArgs) _
        Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged
 
    ''' <summary>
    ''' Raises the <c>PropertyChanged</c> event for the property with the given name.
    ''' </summary>
    ''' <param name="propertyName">The name of the property that has changed.</param>
    ''' <remarks>If there is no property on this class with the given name, then an
    ''' exception will be thrown.</remarks>
    Public Sub OnPropertyChanged(ByVal propertyName As String)
 
        ' Throw an exception if the property doesn't exist
        If Me.GetType().GetProperty(propertyName) Is Nothing Then
            Throw New ArgumentException( _
                String.Format("The property {0} doesn't exist on type {1}.", _
                              propertyName, _
                              Me.GetType().Name))
        End If
 
        RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))
 
    End Sub
 
End Class

This class is very important. There needs to be a method for property change notification (ie: OnPropertyChanged on BaseModelView) instead of just an event (ie: PropertyChanged on INotifyPropertyChanged) because the attribute cannot directly raise an event, but it can call a public method that raises the event. The PostSharp attribute looks like this:

Imports PostSharp.Laos
Imports System.ComponentModel
 
<Serializable()> _
Public Class NotifyAttribute
    Inherits OnMethodBoundaryAspect
 
    Public Overrides Sub OnExit(ByVal eventArgs As PostSharp.Laos.MethodExecutionEventArgs)
        ' Convert to BaseModelView
        Dim notifier = TryCast(eventArgs.Instance, BaseModelView)
 
        ' If the instance is the wrong type then throw an exception
        If notifier Is Nothing Then
            Throw New InvalidOperationException("Cannot raise PropertyChanged event unless instance implements INotifyPropertyChanged.")
        End If
 
        ' Ignore everything that's not a setter
        If eventArgs.Method.Name.StartsWith("set_") Then
            notifier.OnPropertyChanged(eventArgs.Method.Name.Substring(4))
        End If
    End Sub
 
End Class

Note that when you apply PostSharp attribute to a property, you are actually applying the attribute to the two methods that are generated for that property. For example, if you have a property called MyProperty then the compiler will actually generate two methods: get_MyProperty and set_MyProperty. Since OnExit() will actually get called for both of these methods when we apply the attribute to a property, the code has to check whether the getter or the setter was called. Using the attribute is very simple:

<Notify()> _
Public Property Text() As String
    Get
        Return _text
    End Get
    Set(ByVal value As String)
        _text = value
    End Set
End Property

The result is that the PropertyChanged event will automatically be raised after the setter finishes executing and there is no need to hard code any strings! Now you are free to change the name of your property and it won’t break any code.

WPF rendering thread synchronization

Download the sample project here: WpfRenderingThreadSynchronization.zip

In most applications it is necessary to offload long running processes to an alternate thread so that the rest of the program does not lock up during that time. However, it’s not so simple when the long running process is the actual rendering. Separate windows can have their own UI threads (as explained here) but to my knowledge there is no way to use multiple rendering threads on a single window.

The second problem is that rendering is done in big chunks. For example, if you have an ItemsControl that is bound to an ObservableCollection and a loop that adds 1000 items to that collection, you will notice that the elements are not drawn one at a time. Instead the UI will stall for a moment and then every element will suddenly appear on screen. During the time that it is loading, the entire window will be completely unusable. Basically, what happens is that UI changes (like adding an element to an ItemsControl’s ObservableCollection) all get put into a queue and then the rendering thread deals with a whole bunch of them all at once.

There are two problems with this behaviour:

  • The rest of the UI is unusable while this loading takes place
  • It’s not obvious what is happening during the loading period. Since absolutely nothing is happening on screen, the user might think the app is broken.

It turns out that in cases like this where we have many small rendering operations that add up to a large amount of time, we can force the rendering thread to flush out the Windows message queue after each element is added to the collection. This will not only allow the user to see progress (ie: items appearing in the ItemsControl one at a time) but between each item being added other UI updates can take place giving the illusion that there are separate UI threads.

The included sample draws 1000 TextBoxes inside an ItemsControl, but after each element is added the Windows message queue is flushed out using the FlushWindowsMessageQueue function. All the functions does is tell the dispatcher to invoke a delegate that does nothing. The result is that the code blocks at that line until the specified delegate has been run. But since it is at the end of the queue, everything else has to be dealt with first. The function looks like this:

Private Sub FlushWindowsMessageQueue()
    Application.Current.Dispatcher.Invoke( _
        New Action(AddressOf DummySub), _
        DispatcherPriority.Background, _
        New Object() {})
End Sub
 
Private Sub DummySub()
End Sub

When the sample is run with the FlushWindowsMessageQueue() line commented out the whole UI will lock up for a couple of seconds after you click “Refresh data”. However, when the message queue is emptied after each element is added the UI never locks up, even when it is still drawing TextBoxes.

Unfortunately, there are some drawbacks to this method. The most obvious is that it makes the entire rendering operation actually take longer. The trade off is that the first items appear much earlier, but the last items appear later. The technique also cannot be used when the rendering cannot easily be split into many small chunks.

Don’t let “Option Strict Off” make you lazy

VB.NET has the sometimes useful feature of late binding, but this seems to lead to poor code. By default, late binding is enabled (ie: Option Strict is set to Off) allowing for implicit narrowing conversions (no cast). Although there are certainly cases where this is a useful feature that can cut down on the amount of reflection code left up to the programmer, I have found that it is more often a cause of less robust code and needless performance degradation.

With Option Strict Off we can write code like this:

Dim obj As Object = "Hello, World!"
Dim str As String = obj

In this case the code will run just fine, and it saved us the hassle of casting obj to String. However, we will obviously run into problems in a situation like this:

Dim obj As Object = "Hello, World!"
Dim int As Integer = obj

Even though int is an Integer this code will compile, but at runtime there will be an InvalidCastException. This is all pretty simple stuff, but the bottom line is that in this case, Option Strict Off gives a runtime error, while Option Strict On gives a compile error. The value of compile-time errors should not be taken lightly, and in my humble opinion they are a programmer’s best friend. With Option Strict On our first sample only needs a minor change:

Dim obj As Object = "Hello, World!"
Dim str As String = DirectCast(obj, String)

Was it really that difficult just to cast it? Type casting is not an inconvenience, but a necessary precaution requiring the programmer to say to the compiler: “Yes, I did intend to perform a narrowing conversion. It was not an accident”.

As a general rule of thumb, I like to set Option Strict On as the project default (go to Project -> Properties -> Compile) and then add Option Strict Off to code files that require it rather than the other way around.

Verify your property names in INotifyPropertyChanged implementation

Update: I have posted another article here that explains what I think is a better solution to this problem using a simple PostSharp attribute.

When you raise the PropertyChanged event you have to pass it a property name as a string. If there is no property with that name then nothing will happen. The listener will not be notified and no exception will be thrown making the problem very difficult to debug. You can change this behaviour and make the application fail at runtime by adding a simple check to your helper function for the event:

Public Sub NotifyPropertyChanged(ByVal propertyName As String)
    ' Throw an exception if the property doesn't exist
    If Me.GetType().GetProperty(propertyName) Is Nothing Then
        Throw New InvalidPropertyNameException()
    End If
 
    RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))
End Sub

If you put this in a base class for all of your model views (or controllers, or presenters) then you will automatically get this functionality every time, preventing some potentially very annoying bugs.

This still isn’t the ultimate solution because you don’t find out that the property name doesn’t exist until runtime. Ideally, we would get a compile error when the property does not exist. What I would like to do is call the function like this:

NotifyPropertyChanged(AddressOf MyProperty)

This way you wouldn’t have to use a string at all and the compiler would tell you if MyProperty doesn’t exist. Unfortunately, .NET languages only have delegates for functions/subroutines so there is no way to make a strongly typed pointer to a property. Let’s hope they add that in one day, but until then, we’ll have to use strings.