I’ve got SQL Server 2019 Developer Edition installed on my Windows 10 Professional machine. In the last couple of months my Windows profile became corrupted, so I had to abandon it and create a new Windows profile. (Not something I want to do ever again.) What I didn’t realize is now I’ve lost the ability to login into my SQL Server default instance. For whatever reason, although my new profile is in my local Administrators group, my new Windows profile isn’t. (I’d love to know why not – so if anyone knows, please fill me in.)
I’ve been looking around for ways to regain access to my SQL Server. Here’s a promising looking website Recover a lost SA password.
In the first part of this short series on the Action at a Distance I showed how a colleague of mine had, without knowing it, made the application we worked on, only run once. How the first instance would kill any other instances of it coming up. In this second, and final post I’ll show how another mistake was made which also illustrates the action at a distance anti-pattern. I’ve duplicated the pattern in the Action At A Distance 1 application I introduced in part 1. Please refer to that, as it has screen captures of the three windows that comprise Action At A Distance 1.
In Action At A Distance 1, there’s a Save and Cancel button on both the Authors and the Mystery Books windows. Recall that we were instructed to make the original WPF a launch a separate window for each function that the user wanted to do. I duplicated that UI/UX by having a separate Authors window come up, if the user clicked on the Authors button on the main window. The Authors window comes up as many times as the user clicks on the Authors button on the main window. The same is true with the Mystery Books button on the main window causing a Mystery Books window to popup up, as many times as the user clicks on the Mystery Books button on the main window. I discovered that this could cause the application to save data that the user may not have wanted to save. Or just as bad, it might cause the user to stop saving all data, even data they wanted saved, when canceling a save on another window. I copied the logic my co-workers had written into the original WPF app, into Action At A Distance 1. If you want you can look at the code in my GitHub repo for this project. For this part of the tutorial be sure to be in the master branch.
How Saving could be an action at a distance
To see what happened you have to look in a couple places. First the code from App.xaml.cs. In there the original coder wrote this property:
public static AuthorsModel MainDataContext
{
get { return authorsModel; }
set { authorsModel = value; }
}
The coder had written MainDataContext as a global variable seen throughout the application. The next part that contributed to the action at a distance anti-pattern being used was in all of the ViewModels. Here’s the ExecuteSaveCommand() from the AuthorsViewModel:
private void ExecuteSaveCommand()
{
if (! SelectedAuthor.DateOfBirth.HasValue)
{
return;
}
//retrieve relevant data
int selectedAuthorID = SelectedAuthor.ID;
DateTime newDateOfBirth = SelectedAuthor.DateOfBirth.Value;
var rec = App.MainDataContext.Authors.Where(a => a.ID == selectedAuthorID).FirstOrDefault();
if (rec != null)
{
rec.DateOfBirth = newDateOfBirth;
App.MainDataContext.SaveChanges();
}
}
The problem is the App.MainDataContext.SaveChanges() entity framework command. It will save all pending changes. Including ones that the user might not want to save. Here’s the user case where this is a problem. The user opens Authors to make a change to one of the author’s birthdays. Then they open the Mystery Books window and make a change to one of the books publish date. They return to the Authors window, to save the change to that author’s birthday. But they decide that they publish date was fine the way it was, so they click the Cancel button. Well, its too late, they’ve already saved all of the pending changes.
How Canceling can be an action at a distance
In the original WPF app’s cancel function that my colleague wrote, he had a function which undoes all pending changes. I’ve reproduced the logic in the Action At A Distance 1 app:
Here’s how this code can cause an action at a distance anti-pattern mistake, using the Action At A Distance 1 app. Suppose the user opens the Authors app and modify some writer’s date of birth, then before saving their change they open the Mystery Books window and make a change to a publish date. But then they decide they didn’t want to save that change so they cancel the change to the mystery book’s publish date. Now they return to the author’s window and click the Save button. Well, it’s too late, because the above code will have undo all pending changes.
How I resolved these action at a distance problems in the FixedBranch
I removed the global MainDataContext variable from App.xaml.cs.
Then, using the AuthorsViewModel.cs as an example, the ExecuteSaveCommand() I changed as follows:
private void ExecuteSaveCommand()
{
if (! SelectedAuthor.DateOfBirth.HasValue)
{
return;
}
//retrieve relevant data
int selectedAuthorID = SelectedAuthor.ID;
DateTime newDateOfBirth = SelectedAuthor.DateOfBirth.Value;
using (var ctx = new AuthorsModel())
{
var rec = ctx.Authors.Where(a => a.ID == selectedAuthorID).FirstOrDefault();
if (rec != null)
{
rec.DateOfBirth = newDateOfBirth;
ctx.SaveChanges();
}
}
}
I used an local variable, ctx, to open a connection to the database, update the author’s date of birth, saved it, then closed the connection. This is what’s known as the Law of Demeter, which says you’re only to affect objects near by.
Because my Action At A Distance 1 app is so simple I didn’t have a cancel method – merely closing the window is sufficient to cancel the save.
I hope that this will help others to avoid writing action at a distance in their code. To learn more about action at a distance for software development, check out this Wikipedia article.
I’ve been writing code for a long time. The last 10 years or so I’ve delved into learning good software design principles, how to use them, when to use them and so on.
Also, I think it is very good for software developers to learn about software design anti-patterns. There are plenty. Indeed, I sometimes wonder if there aren’t more anti-patterns that good software design patterns. 🙂
One such anti-pattern which I’ve known about for years, but only recently learned it’s name, is known as Action at a Distance. At first I wasn’t sure about that name, but upon reflection I realized that it aptly describes what’s happening. Basically, its this, something happens in the application that was influenced by something else, somewhere else in the application, seemingly unrelated to what the user is currently doing. To the user it might almost look like magic. To a software developer, they might call it a Heisenbug, something that’s very hard to pin down, due to the seemingly arbitrary nature of the bug. Action at a distance bugs are hard to duplicate, unless you understand what is going on with that particular bug. And as all developers know, being able to duplicate a bug is paramount to getting it fixed.
Because of the difficult nature of identifying action at a distance bugs, I thought it would be good to explore some examples, which I have seen in production environments. No, I didn’t write them. But I do have an example of action at a distance anti-pattern, which I’ve taken from a place I worked. The application that we wrote was a Windows Presentation Foundation (WPF) application. Just because this is a WPF don’t dismiss it as some are likely to do. The technology involved isn’t as important as the action at a distance anti-pattern. Hopefully, seeing the code fragments I share here will help you identify the same thing in code you have to maintain or have written yourself. This application is a simple app displaying a few mystery authors and a few of their books. Note: This app is not a full featured app. I put it together in a short period of time, to illustrate the action at a distance anti-pattern, rather than being something that someone would use.
This application, named “Action At A Distance 1” (Originally I thought I might make two apps, but later rejected that idea) is not a typical WPF app. Most WPF apps I’ve seen or helped write, bring up a main hosting window, which other user controls come in through navigation. In this job the UI/UX designer rejected the normal WPF apps navigation, instead he chose a system of having lots of child windows pop up in reaction to users clicking buttons. In keeping with that design and especially as it is a part of the cause of action at a distance anti-pattern, I’ve duplicated it in the Action At a Distance 1 UX design. Here is a screen shot of the “landing page” as we called it:
Action At A Distance 1 start window
If the user clicks on the Authors button, then another window popups up with a small list of authors I’ve entered into a database. There can be as many Authors windows as the user clicks on/cares to bring up (that’s the UX design favored by the project manager/product owner):
September 15, 1890 is Agatha Christie’s birthday
The only field that I have editable in this window, is the date of birth field. (Remember, I wrote this in a short time and was more focused upon illustrating action at a distance, than providing a full featured app.) The Save and Cancel buttons are as they are in the app I helped write at that job.
And finally the Mystery Books button brings up the Mystery Books window, which the user can bring up as many times as they wish, following the pattern given us by the project manager/product owner:
This has the book title, author, the genre of mystery and the date of publication as best I could determine
(You can find my Action At A Distance 1 app at my GitHub repo here. I’ve designed this repo to have two branches, the master branch which illustrates two action at a distance issues, and another branch named FixedBranch, in which I show how I resolved the action at a distance problems.)
In the original WPF app at the job, at one point I wanted to bring up that app a second time. After all, I can bring up Excel or Word more than once. So I tried launching it a second time, but it didn’t come up. After testing it again, I decided to get into the Windows Event Viewer and see what it showed me. There I discovered that I was getting an error message that said, “The process was terminated due to an unhandled exception.” I’ve duplicated the problem in this simple Action At A Distance 1 app. If you either clone or download my repo, then open up the App.xaml.cs file, you’ll see in the constructor these lines of code:
The Logging.CoreEventLog.EnableLogging = true; line invokes the CoreEventLog class. The person who wrote that class, which I’ve copied into this project’s master branch with few changes, has this class level variable assigned:
public static StreamWriter log_file = new StreamWriter(AppDomain.CurrentDomain.BaseDirectory + @"\CoreEvent.log", true);
Later in CoreEventLog you’ll see a function named WriteToLogFile(). Here it is from the master branch:
Putting this all together, you can see that he opens the .log file at the beginning of the application and never closes it! This is the cause of “The process was terminated due to an unhandled exception” error. Once the first instance of Action At A Distance 1 gets a hold of the .log file, no other instance of Action At A Distance 1 can ever run again. At least not from the master branch.
If you have cloned/downloaded my repo, then switching to the FixedBranch you’ll see how I’ve resolved this issue. In the CoreEventLog.cs file I got rid of the class level variable named log_file. Then I changed the WriteToLogFile() method to look like this:
Here you can see that I made use of the using command to instantiate the local log_file variable. Then I’ve followed the original code to write the unhandled exception to the .log file. Once that block of code exists, then the connection to the .log file is closed.
I will resume this tutorial, showing the other action at a distance error illustrated in this small app, in another blog post.
Something happened, when I last tried to push a commit to GitHub on a public repo I’ve started there. It told me that I might expose my private email address, which of course I don’t want to do. I’ve only been using git since last year (2019), so I’m not an expert at git, yet.
I’ve changed what email is used in my local git repo associated with my GitHub repo. However, I’m still getting an error. Talking with the GitHub support people they’ve suggested that it I might have to modify the last email address used in the previous commit to my GitHub repo. I’ve been looking around for a possible way of handling that. This link (interestingly enough on Atlassian) might help. If I’m on the wrong track, I’d love to know!
I’ve begun using Git for my personal software development about a year ago. So far, I’ve been very careful in what I commit and push back to the current branch. Making sure that it’s good before proceeding.
But any good VCS must have a undo function. And so far, I haven’t learned how to use that. Kinda silly of me; as that’s what any VCS should do. So, I’ve been searching the Internet to learn how Git does it. I’ve found this excellent, detailed description on how you can do it with Git on the command line.
Next I’d like to learn how to do this in Visual Studio Code and Visual Studio 2019. I’d appreciate any pointers to good references on doing this, please.
At work we’ve been slowly replacing really old, legacy applications with some more modern technologies. This is so we can better maintain them and put them under source control. (Something that the old “apps” couldn’t do.) Our approach has been to write a single, base project in Visual Studio. Once we did that we branch the main project within source control, into new projects to replace an old, legacy app. (Yes, I know that our habit of branching within source control into a new VS solution which never gets merged back into main, isn’t standard. I’m working on trying to convince my colleagues that isn’t standard procedure.) This was OK, at the beginning. But the violation of the DRY principle has really got me wondering how we could better approach this, especially when it comes to code components which are identical for all of the projects, including the main trunk. Once we get to the point of having 10 or so projects, it’s going to become very tedious to have to make any necessary modifications to the common components within all of those projects.
Shared Projects, a way to help
So, I started to look around for some way of mitigating this. I came across something called Shared Projects within Visual Studio, which I didn’t even know existed. I learned that Shared Projects have been a part of Visual Studio since version 2015. I found a tutorial by Praveem Kumar called Shared Project: An Impressive Feature of Visual Studio 2015 Preview. It is very helpful, with only one problem for me. Praveem put the shared project in the same Visual Studio solution with the 3 client projects that he used to illustrate using shared projects. It’s my hope that at work we’ll create one solution and put one or more shared projects into it. Then later when we branch the main trunk into a new solution, we’d reference the shared project. So, what I’ve done to illustrate how I think we should do it is created 2 VS 2017 solutions, one with the Shared Project and the other a Windows Forms project that consumes the Shared Project, which I’ve shared in my GitHub account.
The Shared Project: MySharedProject
Following Preveem’s tutorial, to a point, I created a MySharedProject solution in VS 2017. (I decided to use .NET Framework 4.6.2.) You can find it in my GitHub repo MySharedProject. My GetEmployeeDetail() method is a little different in the property assignments and I was able to use string interpolation, which wasn’t available to Preveem when he wrote his.
One thing I noticed that was different from what Praveem got, was that I couldn’t compile my version of the MySharedProject. Indeed, it wasn’t even an option:
My Client App: SharedWindowsFormsApp
Next I created a new VS 2017 solution that I called SharedWindowsFormsApp, which I’ve got in a different GitHub repo. (Please note that on my system, I put both repos under one folder. Also note that I decided not to replicate both the MVC and console apps that Praveem did.) My code for SharedWindowsFormsApp isn’t really different in any way from Praveem’s. So, how to make SharedWindowsFormsApp aware of the shared project? I right mouse button clicked on the solution and choose Add Existing Project:
Looking for the shproj file:
Now my SharedWindowsFormsApp’s solution looks like this:
Of course, I had to add a reference to the shared project, in SharedWindowsFormsApp project:
One thing that I thought would happen is I thought Visual Studio would copy the MySharedProject code under that SharedWindowsFormsApp solution, into a folder named MySharedProject. I opened up File Explorer on my Windows 10 machine to verify that, but found I was wrong! So, I opened up the SharedWindowsFormsApp.csproj file to see what was going on. At the bottom I found this:
Looking at this you can see the first Import is a relative reference to the place, on my machine, where I found the .shproj file. And it has the attribute of Label=”Shared”.
Once that was done, I could build SharedWindowsFormsApp and it ran fine:
I’ve been trying for months now to learn how to use Visual Studio Code (Code) with Visual Studio Team Services (VSTS). The biggest problem is not always having long enough time to devote to learning it. So, to help me out I’m making a link as to where I’m at in this learning process. This blog post Personal Access Tokens & VSTS so far is very helpful.
Everything below is what I wrote, basically on the fly as it was happening. Please excuse the somewhat haphazard blog post.
The Problem
After creating a new Web API project and only adding the necessary information for the dev ADFS server, I got this error:
System.IO.FileLoadException
HResult=0x80131040
Message=Could not load file or assembly ‘Microsoft.IdentityModel.Protocols.WsFederation, Version=5.2.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35’ or one of its dependencies. The located assembly’s manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
Source=Microsoft.Owin.Security.ActiveDirectory
I called Microsoft technical support on 7/20/20178 to resolve this issue.
The tech support enabled something called Fusion logging, to help her diagnose what the issue was. She pointed me to this Stack Overflow post describing how to enable Fusion logging in the Registry.
Running Visual Studio was slow after that
The Fusion logging did slow down VS startup, obviously I’ve set both the EnableLog and ForceLog keys to 0 (they were set to 1). I had to reboot, to get it to work a bit faster.
Note: Do NOT simply delete the Registry cluster
Don’t just delete the registry cluster at Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Fusion
There are sub-folders (sub registry clusters) under that cluster that belong there! (e.g.: GACChangeNotification, NativeImagesIndex and PublisherPolicy).
We learned this week that Microsoft intends to discontinue their excellent music service, known as Groove. This for me very sad news. I’ve been a member of Microsoft’s music services since back in the Zune days. In the last 12 months I’ve really come to love Groove. I love its suggesting new playlists for me. I’ve listen to many of them. Some, I didn’t care for, but others I’ve loved. Its introduced new artists and music to me.
Then they made Groove even better by adding music videos! I had no idea how much I’d love watching music videos!
Yes, I know that the transition is going to Spotify. Yes, I know that many people love Spotify. But this still is a very, very sad time. And at least from the time I’ve spent with Spotify it didn’t deliver the music I liked, nor (as far as I know) does it provide music videos.
Oh well, we’ve no choice in the matter. I’ll just enjoy Groove for the time I have left with it and then move everything to Spotify.