EF Core 2.0 expects your “Application” to hold your data context (010-100 top left figure 2), but if you follow best practices and patterns your context will reside in the data layer (010-020-010 in green below figure 2) and you’ll receive this message when you try to “Add-Migration” via the Package Manager Console.

Figure 1 Package Manager Console error message
I love Entity Framework Core 2.0 because our entities can remain POCO objects, effectively allowing us to decouple them from our layers (reference 010-030 ContactDonation.Model in middle-right of image below); later if I have to swap out the EF data access layer (010-020-010 in green below), for lets say an Azure data layer, my presentation and business logic layers won’t be affected.
It is quite problematic that EF Core 2.0 expects to see my data context in the main application (in my presentation layer). Particularly since my data access layer for the ContactContext will be reused by other business logic layers, e.g., I might reuse it in a totally different application. Note to mention that I may want to swap out my presentation layer (which has no business logic in it), e.g., for an ASP.NET application. But I have a work-around….

Figure 2 Separated presentation – MVPVM pattern (for decoupled frameworks)
By “linking” the ContactContext class from my data access layer project to my application (ContactDonationWpf), I can effectively fool Visual Studio into thinking the data context resides in the main application to complete processing. This permits me to keep my data context neatly decoupled while allowing my POCO entities (below) in a separate ContactDonation.Model project that can be referenced by all layers.
namespace ContactDonation.Model
{
public class Contact
{
public string ContactId { get; set; } // PK
public string UserId { get; set; } // Users use
public string Email { get; set; }
public string Title { get; set; }
public string Name { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Middleinitial { get; set; }
public string NickName { get; set; }
public string Spouse { get; set; }
public string Realtives { get; set; }
public string Website { get; set; }
public ICollection<Address> Address { get; set; }
public ICollection<PhoneNumber> PhoneNumbers { get; set; }
public ICollection<Organization> Organizations { get; set; }
public ICollection<Tag> Tags { get; set; }
public string Notes { get; set; }
public Contact()
{
PhoneNumbers = new HashSet<PhoneNumber>();
Organizations = new HashSet<Organization>();
Tags = new HashSet<Tag>();
}
}
public class Address
{
public string AddressId { get; set; } // PK
public string Type { get; set; } // Billing, Residence
public string Street { get; set; }
public string Street2 { get; set; }
public string City { get; set; }
public string State { get; set; }
public string Zip { get; set; }
}
public class Organization
{
public string OrganizationId { get; set; } // PK
public ICollection<Address> Addresses { get; set; }
public ICollection<PhoneNumber> PhoneNumbers { get; set; }
public Organization()
{
Addresses= new List<Address>();
PhoneNumbers = new HashSet<PhoneNumber>();
}
}
public class PhoneNumber
{
public string PhoneNumberId { get; set; } // PK
public string Type { get; set; } // Cell, Work, Home
public string Number { get; set; }
}
public class Tag
{
public string TagId { get; set; } // PK
public string Name { get; set; }
public string Notes { get; set; }
}
}
Source code: BillKrat/OpenLiveWriter (CodeSnippet)

It was great news that the Live Writer application was released as open source – initially there was some momentum behind it and as a result we have source code that we can easily compile in Visual Studio. Unfortunately, the revisions made rendered the existing plug-ins useless with no readily available documentation or process for being able to utilize them. This prompted me to start an adventure so that I could get my favorite “Code Snippet” plug-in back.
The source branch I reference in above link is my fork on GitHub where I compile it under Visual Studio 2017 after making some tweaks; more specifically – fixed issues that crashed the application’s internal processing.
In a nutshell to get the “Code Snippet” plug-in working you have to copy the SharedDll contents (OpenLiveWriter.BlogClient.dll) to the click once application folder (instructions below) and then copy the SharedInstall contents into the “Open Liver Writer” plug-in folder.

There are a couple of issues at play here that cause our plug-in dilemma:
- An exception in the blog providers causes the plug-in logic to be bypassed
- The plug-ins are compiled with an API that no longer exists – the namespace has changed.
Exception is thrown that causes logic to be bypassed (if applicable - above works with latest release)
If you were to download the source for my Visual Studio 2017 branch (reference link above) and search for “BillKrat” you will find the minor revisions made that permitted the application to run without internal crashes. Note: I did provide a pull request.
Below you’ll see that I remarked out a provider that was causing an exception to be thrown bypassing the logic that checks the Plug-ins folder (shown in image above). To resolve this you’ll need to replace the OpenLiveWriter.BlogClient.dll.

To replace the dll in the click-once application you can simply launch the application, load the Task Manager, right click on the executing application, and select “Open file location” as shown in the image below. Once opened in the file explorer you can replace the OpenLiveWriter.BlogClient.dll. Upon subsequent usage of the click-once application you will be able to load plugins from the plug-in folder.

The plug-ins are compiled with an API that no longer exists
Once I could get the dll to load from the open source code, it then crashed because the WIndowsLive.Writer.Api is no longer available, the namespace was changed to OpenLiveWriter.Api. This effectively breaks all existing plug-in code. My initial knee-jerk reaction was to get .NET Reflect (version 6 was a free version if you can still find it on the internet) and have it extract the code from the existing dll. I then removed the outdated reference, referenced the new OpenLiveWriter.Api project, fixed minor compile issues (from Reflector) and Walla! I had a functional code snippet plug-in. I later found that there are numerous open source plug-ins for Windows Live Writer that can downloaded, retro-fitted with the new OpenLiveWriter.Api and dropped into the applicable folder without having to use Reflector. Note: as of this writing I only use the Code Snippet plug-in.

As I design the Visual Studio project structure for my new open source Contact Manager, which I am writing for a local religious organization pro bono, I have to keep a few things in mind:
- My vision statement of “create a contact management system for the web, desktop, and phone utilizing the same code-base. It should be extensible so that additional modules, such as a donation module, can be easily added reusing the existing infrastructure and components”.
- The contact manager utilizes user information – these are components that will be reusable across future modules as well as applications. We’ll want to place these components in a Gwn.Global.xxxxx projects (figure 1).
- The desktop and web applications can access the business [and thus data access layers] directly – important because the client wants to have an on-site SQL database as well as a “cloud” based SQL database (they will be synchronized). The desktop app will be configured for the on-site database and the web application for the cloud database (figure 3)
- The mobile applications: tentatively Google Kotlin for Android, and Apple Swift for IOS, will be mainly presentation layers consuming a service layer for the cloud database (figure 2).
The use of MVVM over MVPVM has been a debate that I usually have with team members during initial planning, in some cases I win, other times I lose – I’m a team player so when the decision is made, I roll up my sleeves and make it work.
While planning/diagramming the project structure that I will use for this solution, it quickly became apparent why the Model-View-Controller (MVC) Presentation Model had architects of the day wanting to evolve to the Model-View-Presenter (MVP) – Martin Fowler discusses it in his article on GUI Architectures.
Before continuing… What does Presentation Model have to do with MVVM? This tidbit of information is the contextual glue that bridges the gap between our early architects with todays – we lack a common core of experience so we missed this important lesson. John Gossman, the founding father of MVVM noted that MVVM is a WPF-specific version of the PresentationModel Pattern, versus the ApplicationModel pattern which permitted the view model to access the view – seen as a “a bit of dirty work”. The PresentationModel pattern does not allow access to the view as it would prevent the reuse of the view model with other views, which is a well understood MVVM pattern rule.
When we view the power of separated presentation, we have to do so within the context of MVP versus MVVM, because as our early architects taught us – MVP solves the problems of MVC. One such problem rears its ugly head in the diagram below – at least if we were to use MVVM for this project, which is not my preference. With MVVM, our ViewModel[s] would be tightly coupled to our business logic layer and data transfer objects - we could not reuse them in any other module [without pulling in the kitchen sink]. In contrast the MVPVM ViewModel and View are completely decoupled and these components can be easily reused. Note on the right that my Gwn.Global.Presentation project is planning to include all reusable views and view models for user specific information [which makes sense as user information is reusable].
Ironically, Microsoft’s ASP.NET MVC is the same pattern as MVPVM (presentation layer in figure 1), the irony being that ASP.NET MVC and SmallTalk MVC have nothing in common as the “controller” has a total different meaning, yet they adopted the newer MVP pattern using an old pattern name. Martin Fowler says the following about this in his article on GUI architectures:
“Different people reading about MVC in different places take different ideas from it and describe these as 'MVC'. If this doesn't cause enough confusion you then get the effect of misunderstandings of MVC that develop through a system of Chinese whispers.”
The lesson you don’t want to miss here - a rose by any other name is still a rose. Microsoft didn’t use MVVM, aka PresentationModel pattern, for its ASP.NET MVC framework - they used the MVP [VM] pattern.

Figure 1 draft project structure

Figure 2 mobile service layer

Figure 3 desktop/website
Where the built-in Inversion Of Control (IOC), aka Dependency Injection (DI), container of ASP.NET MVC will meet most needs, sometimes we’ll want to utilize more advanced features of alternate IOC containers. In the example below we are configuring for the use of Autofac (line 56), using a pattern consistent with existing code – an extension method.

The extension method AddAutofacProvider code follows below:

Note on line 13 above that we have an optional “builderCallback” action. This provides the Startup ConfigureService method access to the builder instance created above on line 16. Below on lines 56-60 is an example of how it might be used:

Source code follows:
public static IServiceProvider AddAutofacProvider(
this IServiceCollection services,
Action<ContainerBuilder> builderCallback = null)
{
// Instantiate the Autofac builder
var builder = new ContainerBuilder();
// If there is a callback use it for registrations
builderCallback?.Invoke(builder);
// Populate the Autofac container with services
builder.Populate(services);
// Create a new container with component registrations
var container = builder.Build();
var provider = new AutofacServiceProvider(container);
// When application stops then dispose container
container.Resolve<IApplicationLifetime>()
.ApplicationStopped.Register(() => container.Dispose());
// Return the provider
return provider;
}
Source code available: HERE
With ASP.NET MVC Core 2, much of the configuration work is already done for us; it is configured for appsettings.{Environment}.json right out of the box. Line 29 is all you’ll require for the Startup method.

I added the following extension method (line 53 above) to simplify my ConfigureService code [being consistent with existing code]:
public static void AddAppSettings(this IServiceCollection services, IConfiguration configuration)
{
var section = configuration.GetSection(nameof(AppSettings));
services.Configure<AppSettings>(section);
}
My appsettings.development.json configuration file has a section “AppSettings” which contains one setting [as of this writing] it is “Environment”. For consistency I created a AppSettings class that has a property name of Environment as required by the above “services.Configure<AppSettings>(section)” process; it will populate all AppSettings properties of the same name of the settings within the configuration file.
If you examine the Property page of your project you’ll find that the ASPNETCORE_ENVIRONMENT variable has already been set and defaults to “Development” – this will result in the appsettings.development.json file being used. Since there are no other configuration files if you were to use any other name, e.g., “Production” it will default to the appsettings.json file.

All that remains is to use constructor injection to retrieve the configuration settings. With default usage [out-of-the-box] you can use the “IOptions<AppSettings> settings” parameter as shown on line 29 of the image below. To retrieve an instance of AppSettings you’ll need to use the Value property of settings (reference line 33 below). However, there is more information available [by default] that I want to have available to my application, so I also registered an “IAppSettings appSettings” (line 30) implementation that will provide all of the environment variables as well (see red arrow for AppSettings). Note: I provide both methods for demonstration purposes only, I will only be using IAppSettings in my code.

So if your only interested in the out-of-the-box usage, you are done here. If you are interested in how to have the environment variables (in the case above 83 of them), please read on.
In the Startup class I not only modified ConfigureServices (as shown above) but also made an update to the Configure process as shown in bold below:

The UseAppsettings extension method (line 19 below) uses the service provider to obtain applicable services and then calls the AppSetting class Initialize method with an event argument that contains services.

The Initialize method above uses the event arguments (services) to retrieve and populate the ‘Values” property with the available settings.