Red-Green-Code

Deliberate practice techniques for software developers

  • Home
  • About
  • Contact
  • Project 462
  • CP FAQ
  • Newsletter

Time Tortoise: Resolving Dependencies, Part 4

By Duncan Smith Dec 9 0

Process Monitor

This is one in a series of articles about Time Tortoise, a Universal Windows Platform app for planning and tracking your work schedule. For more on the development of this app and the ideas behind it, see my Time Tortoise category page.

Last week, I upgraded the Time Tortoise projects to .NET Standard 2.0, and also upgraded related NuGet packages that had .NET Standard 2.0 versions. The upgrade was mostly successful, but it broke a few unit tests. In the process of fixing them this week, I had to find yet another technique for resolving dependencies.

Microsoft.Data.Sqlite, EF Core, and SQLitePCL.raw

Time Tortoise uses SQLite to store activities, time segments, and other time tracking data. Since SQLite is written in C, it’s not conveniently accessible from a .NET application. Fortunately, people have built interfaces from .NET to SQLite. For example, there’s the Microsoft.Data.Sqlite.SqliteConnection class for creating a connection to a SQLite database. And Entity Framework Core abstracts away most of the database-specific details of reading and writing data.

In v2.0, Microsoft.Data.Sqlite and EF Core have adopted SQLitePCL.raw, a library that provides low-level access to SQLite. This change is intended to be mostly transparent to application code, but like many changes involving package upgrades, it affected Time Tortoise unit test projects.

Unit Test Errors

The first error I ran into was this one, which occurred in my database integration tests:

System.Exception : This is the ‘bait’. You probably need to add one of the SQLitePCLRaw.bundle_* nuget packages to your platform project.

Bait refers to the Bait and Switch Pattern, a trick used when building Portable Class Libraries (like SQLitePCL.raw) to take advantage of platform-specific features that wouldn’t normally be available to a PCL.

The error message provided a clear fix, so I took its advice and added the SQLitePCLRaw.bundle_green NuGet package to the projects that needed it.

Once I did that and re-ran the unit tests, I got a new message when attempting to instantiate a SqliteConnection:

Message: System.TypeInitializationException : The type initializer for ‘Microsoft.Data.Sqlite.SqliteConnection’ threw an exception.

—- System.Reflection.TargetInvocationException : Exception has been thrown by the target of an invocation.

——– System.DllNotFoundException : Unable to load DLL ‘e_sqlite3’: The specified module could not be found. (Exception from HRESULT: 0x8007007E)

I found a few references to this error online, including a GitHub issue that closely matched my configuration: EF Core 2.0, unit tests, and an in-memory SQLite database. According to the issue discussion, the root cause is related to “transitive packages in project references in NuGet.” That sounds similar to the many dependency problems that I have run into with unit tests. But I wasn’t able to resolve the error using any of the advice in that issue, so I decided to do some more investigation.

DllNotFoundException

A few weeks ago, I built a simple tool to facilitate missing dependency investigation. But it wasn’t giving me any information about this missing DLL. The problem: e_sqlite3.dll is an unmanaged DLL, which means the standard .NET facilities that my tool is based on won’t help.

A web search for debugging DllNotFoundException turned up the perfect Stack Overflow answer for this problem: use Process Monitor. Of course. That tool logs all file references, including .NET assemblies and any other file type. So if a process is trying to load e_sqlite3.dll, Process Monitor should show exactly where the process thinks it should be.

On first run, the tool is very noisy, since it returns all file activity in the system. After filtering out the noise, I found that vstest.execution.x86.exe (the Visual Studio unit test execution engine) was looking not for e_sqlite3.dll, but for a file called VCRUNTIME140_APP.dll. Presumably, the C-based SQLite engine needs this C runtime library, and for some reason the unit test runner can’t find it.

I found a copy of the DLL in C:\Program Files\ WindowsApps\ Microsoft.VCLibs.140.00_14.0.24605.0_x86__8wekyb3d8bbwe. From previous dependency debugging experience, I knew that C:\PROGRAM FILES (X86)\ MICROSOFT VISUAL STUDIO\ 2017\ ENTERPRISE\ COMMON7\ IDE\ COMMONEXTENSIONS\ MICROSOFT\ TESTWINDOW\ is where the test runner would look for it. After copying it there, my tests all ran successfully.

Although my assembly binding log parser is the appropriate tool in most cases for .NET dependency investigation, it’s good to have a way to also investigate missing unmanaged dependencies.

Categories: TT

Prev
Next

Stay in the Know

I'm trying out the latest learning techniques on software development concepts, and writing about what works best. Sound interesting? Subscribe to my free newsletter to keep up to date. Learn More
Unsubscribing is easy, and I'll keep your email address private.

Getting Started

Are you new here? Check out my review posts for a tour of the archives:

  • Lessons from the 2020 LeetCode Monthly Challenges
  • 2019 in Review
  • Competitive Programming Frequently Asked Questions: 2018 In Review
  • What I Learned Working On Time Tortoise in 2017
  • 2016 in Review
  • 2015 in Review
  • 2015 Summer Review

Archives

Recent Posts

  • Quora: What to Do When You’re Stuck on a Competitive Programming Problem April 14, 2021
  • Quora: How to Get Better at Competitive Programming April 7, 2021
  • Quora: Is LeetCode Useful for Beginning Competitive Programmers? March 31, 2021
  • How to LeetCode March 24, 2021
  • LeetCode 322: Coin Change March 17, 2021
  • LeetCode 152: Maximum Product Subarray March 10, 2021
  • LeetCode 856: Score of Parentheses March 3, 2021
  • LeetCode 11: Container With Most Water February 24, 2021
  • LeetCode 47: Permutations II February 17, 2021
  • LeetCode 897: Increasing Order Search Tree February 10, 2021
Red-Green-Code
  • Home
  • About
  • Contact
  • Project 462
  • CP FAQ
  • Newsletter
Copyright © 2021 Duncan Smith