Disable Entity Framework Code First Initialization Logic

When you use the Entity Framework Code First approach to build your database, EF’s default behavior is to verify if a database exists when the application runs the first time. In case it does not exist, EF creates it.

There might exist some situations when there is no need to run this initialization logic, e.g. when you run unit tests on an existing database.

Disabling the initialization for a given context type is really simple. This call will do the job:

System.Data.Entity.Database.SetInitializer<TContext>(null);

I found a sample on Stack Overflow where a custom System.Data.Entity.IDatabaseInitializer<TContext> was implemented, having an empty InitializeDatabase method. But why create and maintain a class when we can get the same result for free.

Setting the initializer to null should be performed before the database is accessed the first time by the context type. I prefer to put this into the initialization method of my application or inside of the TestInitialize method of my unit test classes. Putting this code into the ctor of the DbContext class will lead to an unneeded number of calls every time an instance of the context class is created.

And because I forgot to do so, an additional hint concerning the unit tests: It is not sufficient to disable the initialization logic for the DbContext type defined / used in the test project. Also, the initializer of the DbContext type used by the application classes, defined in the application project, has to be set to null.

Links

Understanding Database Initializers in Entity Framework Code First

Handle Race Conditions / Concurrency in Code First Entity Framework Applications

Preface

A common scenario in developing applications is the handling of concurrent database updates.

Given there is an application to manage customers, that is used by multiple users simultaneous.

User U1 reads the data of customer C1. While user U1 is looking at this data, user U2 reads the data of customer C1 too. Meanwhile, user U1’s phone is ringing. She picks it up. User U2 changes some of the customer’s data and saves it to the database. User U1 finishes the phone call, make some changes to the same customer, and saves it too.

Without handling the race condition or concurrency, al changes made by user U2 will be lost in this example. Handling it, the application should not save the changes made by user U1 and inform her that the customer’s data was changed in the meantime by another user.

In this post I will show an approach and sample code on how an application using the Entity Framework and the Code First approach can handle this.

Code Preparation

There is only one step required to make Entity Frame do all the work for you: Define a Version property in the model class (the name of the property does not matter at all), and decorate it with a Timestamp attribute.

/// <summary>
/// This column will be used by EF for race condition validation.
/// </summary>
[Timestamp]
public byte[] Version { get; set; }

Believe it or not – this is all you have to do (in case you are using the Code First approach).

Entity Framework will set the Version property to a value when the record is inserted into the database. Every time EF updates the record, it verifies that the value of the column has not changed. Doing an update, the version is increased.

Handling a Race Condition

EF throws a DbUpdateConcurrencyException in case a record was changed since the data was read.

So you have to catch this exception whenever your application updates or deletes database records and inform the user that the data was changed. In case there is no user to be informed, e.g. if this happens in a background process, you have to implement an appropriate error handling mechanism.

Using the Sample

To see EF Concurrency Handling in action, you can use the sample application.

There are two “clients” implemented, accessing both the same database record. Take these steps to provoke a concurrency exception:

  • Read the record for client 1 (press the Read Record button of the Client 1 group)
  • Read the record for client 2 (press the Read Record button of the Client 2 group)
  • Update the record for client 2 (press the Update Record button of the Client 2 group)
  • Try to update the record for client 1 (press the Update Record button of the Client 1 group)

The result should look like this:

Sample when Race Condition occurred

Some Sample Details

The sample code was created using Visual Studio 2013 Ultimate and Entity Framework 6.1. In case you use an older version of Visual Studio, you might have to create an empty solution and add the files to it.

The application expects a SQL Server instance (not SQL Server Express) installed on the local machine having the default server name (MSSQLSERVER). In case you do not have a SQL Server with this name running on your machine, you have to change the connection string in the app.config file before you can run the sample.

On the SQL Server, the application creates a database named EntityFrameworkRaceCondition. Please make sure to have the appropriate rights to create a database when you run the sample.

Links

Microsoft Data Developer Center Entity Framework

Entity Framework / Get Started / Code First to a New Database

Entity Framework Tutorial Update Entity Using DbContext

Wikipedia Race Condition

Sample Application

Paging Made Easy with ASP.NET MVC 5, Entity Framework 6 and PageList.Mvc

Preface

In former days, implementing paging sometimes took a little bit of time. That was independent from the used platform, native Windows Client or Web or whatever.

Fortunately, that was then and this is now. Implementing paging in an ASP.NET MVC 5 Entity Framework 6 application really became simple. Just a few lines of code, and you’re done.

The Basics

The basics of paging in ASP.NET MVC are described by the Getting Started with EF 6 using MVC 5 tutorial Sorting, Filtering, and Paging with the Entity Framework in an ASP.NET MVC Application.

As the title says, you need EF 6 and MVC 5. The author Tom Dykstra suggests to use PagedList.Mvc. NuGet Must Haves lists this package on top of the Top 20 packages for paging. So I thought I’ll give it a try.

Using PagedList.Mvc

The usage is simple. As described by the ASP.NET tutorial, the package needs to be installed. I used the menu: Tools / NuGet Package Manager / Manage NuGet Packages for Solution….

Changing the View

The model of the view that should contain paging needs to be changed from IEnumetablle<MyModel> to PagedList.IPagedList<MyModel>. Also, the using of PagedList.Mvc and a link to the PagedList stylesheet needs to be added. After changing the code, the first tree lines of the view look like this:

@model PagedList.IPagedList<MyModel>
@using PagedList.Mvc;
<link href="~/Content/PagedList.css" rel="stylesheet" 
  type="text/css" />

In case you want to show the current page and the total number of pages, add something like this to the appropriate place.

Page @(Model.PageCount < Model.PageNumber ? 0 : Model.PageNumber)
 of @Model.PageCount

The last change is adding the paging buttons into the view.

@Html.PagedListPager(Model, 
  page => Url.Action("Index", new { page }) )

Changing the Controller

Because the view expects a different kind of model, the controller has to generate it. And because we need to return the content of different pages, the requested page is passed as a parameter. Given that db.MyModels returns something of type MyModel, the controller might look like this:

public ActionResult Index
  (
    int? page
  )
{
  var items = for item in db.MyModels select item;

  return (View(items.ToPagedList(pageNumber: page ?? 1, 
    pageSize: 10)));
}

That's really simple, isn't it.

Paging Extended

The code above works really good. But I want to extend the paging a little bit.

Let the User Choose

The number of items shown per page is fix in the sample above. I do not like that. So I added a dropdown list to the view to let the user choose how many items per page will be displayed.

The list of items shown by the dropdown list is generated by a helper method to make it reuseable.

public static class DefaultValues
{
  ...
  public static SelectList ItemsPerPageList 
    { 
      get 
      { return (new SelectList(new List { 5, 10, 25, 50, 100 }, 
        selectedValue: 10)); 
      } 
    }
  ...
}

To use this list, the view defines a local variable.

SelectList itemsPerPageList = DefaultValues.ItemsPerPageList;

And the dropdown list is placed wherever I like using the HtmlHelper

@Html.DropDownList("ItemsPerPage", itemsPerPageList, 
  new { @id = "ItemsPerPageList" })

To have the correct number of items per page shown when the user switches the page, we need to pass the current number of items to the controller. Therefor the HtmlHelper for the paging buttons needs to be extended.

@Html.PagedListPager(Model, page => Url.Action(ActionNames.Index,
  new { page, itemsPerPage = ViewBag.CurrentItemsPerPage }));

As you can see by this code, the controller needs some changes too.

public ActionResult Index
  (
    int? itemsPerPage,
    int? page
  )
{
  ViewBag.CurrentItemsPerPage = itemsPerPage;

  var items = for item in db.MyModels select item;

  return (View(items.ToPagedList(pageNumber: page ?? 1, 
    pageSize: itemsPerPage ?? 10)));
}

Handling an Empty List

From what I noticed, the Model of the view is null in case the list itself does not contain any items.

The extension method PagedListPager is not able to handle that. And of course, when showing the current page and the total number of pages, accessing a null reference leads to an exception too.

To avoid these exceptions, some more code is required.

@if (Model != null
  && Model.PageCount > 0)
  {
    <div>
      Page @(Model.PageCount < Model.PageNumber 
             ? 0 : Model.PageNumber) 
      of @Model.PageCount
    </div>
  }
@if (Model != null)
  {
    @Html.DropDownList("ItemsPerPage", itemsPerPageList, 
      new { @id = "ItemsPerPageList" })
}

Minor Stylesheet Additions

In my ASP.NET MVC application, I have a footer defined in the _Layout.cshtml file. In some cases I saw that the paging buttons partly were overlapped by the footer. To avoid this, I added a bottom margin to the pagination container style and put this into the Content/Site.css file:

.pagination-container {
  margin-bottom:25px;
}

Conclusion

Even with these small additions, paging is made really easy. What I was not looking at is the performance of the database access. For web applications with small databases, this does not seem to be important from my point of view. In case you do have a large database and complex database requests where performance is an issue, I think it's worth to check out the impact of this implementation.

Links

ASP.NET Tutorial: Sorting, Filtering, and Paging with the Entity Framework in an ASP.NET MVC Application

PagedList.Mvc on NuGet

NuGet Must Haves Top 20 NuGet packages for paging

Handle Deactivated JavaScript in ASP.NET MVC Web Application

Preface

Depending on what your ASP.NET MVC Web application is supposed to do, it might be necessary that the client’s browser has JavaScript support enabled.

If this is not the case, maybe you want to make sure the user will be informed and cannot use the application.

And because there is no JavaScript available, this has to be done in a non-script way.

Use The noscript-Tag & Redirect

To handle all this without any script is quite simple. HTML offers the noscript tag.

Inside the noscript area, one can add whatever HTML code is required.

Since I want the user to be redirected to another page, I will use meta http-equiv="refresh" content="0;…" to redirect the user to the page explaining that JavaScript is required to use my application.

Add It To The Layout Page

To make sure the user will be redirected independent which page should be opened, I add the noscsript area to the _Layout.cshtml page.

And because I do use a meta tag, the code is placed into the head area to avoid warnings that meta elements cannot be nested inside the body element.

In case you use different layout pages in your application, you should put the redirection code into a partial view and add this to all of your layout pages. If there is the need to change the redirection, there will be only one place that needs to be changed.

NoJScript Controller And View

I do have a ASP.NET MVC application, so want to redirect to an appropriate controller when JavaScript is disabled, not to a HTML page.

Accordingly, I add the NoJScript controller with an Index view to my project and redirect the user to /NoJScript. The view is used to inform the user that JavaScript support is required and can contain all non-script elements that are needed.

It is important that this view does not use the layout page itself. Otherwise there will be an endless redirection loop, because when the view is opened, the browser detects there is no JavaScript enabled, and again redirects to this view, and so forth.

Access Restrictions

In case you restrict access to your application by setting the AuthorizeAttribute either to your controller or by adding

filters.Add(new System.Web.Mvc.AuthorizeAttribute());

to the App_Start/FilterConfig.cs, remember to set the AllowAnonymousAttribute to the Index method of the NoJScript controller. Otherwise, the browser is hooked in an endless loop, switching between the login page and the JavaScript required page.

Putting It Together

Here are all changes listed.

In the _Layout.cshtml page, this section is added to the head element:

<head>
…
<noscript>
  <meta http-equiv="refresh" content="0;url=/NoJScript" />
</noscript>
…
<head>

The NoJScript controller is really simple:

public class NoJScriptController : Controller
{
  //
  // GET: /NoJScript/
  [AllowAnonymous]
  public ActionResult Index()
  {
    return View();
  }
}

And the view should contain a little bit more information than this sample:

@{
  ViewBag.Title = "JavaScript required";
  Layout = null; // <= Important!
}

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>@ViewBag.Title - My MVC App</title>

  @Styles.Render("~/Content/css")
  @Scripts.Render("~/bundles/modernizr")

</head>
<body>
 To use this application JavaScript is required.
</body>

Create a 1:1 Table Relationship using Entity Framework

Preface

My database roots are pure SQL. When I create a database, I use an Excel sheet for documentation purposes, which creates SQL statements to build up the tables.

Table relationships (parent / child) with foreign keys I do define by hand, like the good old craftsmen do. It’s simple for me, and having the appropriate SQL code from another project, it takes a few seconds to adapt it to the new tables.

But from time to time one should try something else, so I decided to use the Entity Framework (EF) Code First approach for a new project I started. This post was written to document the required steps for later re-use.

Starting Point

As a starting point, I built an ASP.NET MVC 5 application with EF 6 and “Individual User Accounts” authentication, using Visual Studio 2013 Update 1.

Project Settings

Because the key of the AspNetUsers table is a string containing a GUID, I wanted to add a UserProfile table to map the GUID to an integer. This integer value will be used by the application to map other data to specific users. From my point of view, an integer is much more readable than a GUID.

Adding the Model

Since I was using the Code First approach, I added a class called UserProfile to the models. To link the UserProfile to the user main table, it needs to contain a property of type ApplicationUser. This class is created by the ASP.NET MVC project template and maps to the database table dbo.AspNetUsers.

I also wanted to keep the date and time when a user was created, so the UserProfile class got a CreationDate property. And because it seems that EF Code First does not support database default values, this property is set by the default constructor of the class. As a result, UserProfile looks like this:

public class UserProfile
{
  public long Id { get; set; }

  [Required]
  public DateTime CreationDate { get; set; }

  public ApplicationUser User { get; set; }

  public UserProfile()
  {
    CreationDate = DateTime.Now;
  }
}

To make sure the UserProfile data will be read when the ApplicationUser is accessed, I added a UserProfile property to this class, which is located in the file Models/IdentityModels.cs.

public class ApplicationUser : IdentityUser
{
  public virtual UserProfile UserProfile { get; set; }
}

Try to Create the Database Tables

After creating the database itself using SQL Server Management Studio and changing the connection string in Web.Config, I used the Package Manager Console to create the database tables. The console can be opened via Tools / NuGet Package Manager / Package Manager Console (or use Quick Launch [Ctrl+Q]).

To enable database migration, I first ran Enable-Migrations, which failed.

The error message was “Unable to determine the principal end of an association between the types ‘OneToOneTableRelationship.Models.UserProfile’ and ‘OneToOneTableRelationship.Models.ApplicationUser’. The principal end of this association must be explicitly configured using either the relationship fluent API or data annotations.“.

What does that mean? In short, EF does not know how the UserProfile and ApplicationUser relationship should be organized. Which one is the parent, and which one is the child. There are two ways on how to define this: by the relationship fluent API (means coding) or data annotations (means attributes on class properties).

Declare the Principal End of Association

I decided to use the coding approach and added the method OnModelCreating to the context class ApplicationDbContext (can be found in Models/IdentityModels.cs).

To complete the database context, I also added a DbSet<UserProfile> to gain access to that table.

public class ApplicationDbContext 
  : IdentityDbContext<ApplicationUser>
{
  public DbSet<UserProfile> UserProfile { get; set; }

  public ApplicationDbContext()
    : base("DefaultConnection")
  {
  }

  protected override void OnModelCreating
    (
    DbModelBuilder modelBuilder
    )
  {
    modelBuilder.Entity<UserProfile>()
      .HasRequired<ApplicationUser>(profile => profile.User);

    base.OnModelCreating(modelBuilder);
  }
}

Create the Database Tables

Now that EF knows how to build up the relationship, I created the database tables with two steps at the Package Manager Console.

Add-Migration Initiallize

created the code for the initial table setup. This code is located at the Migration folder.

Update-Database

ran that code and created the database tables.

After the update, the database contains, beside others, these two tables:

AspNetUsers tableUserProfiles table

Setting Up the Controller

When Visual Studio creates the controller class from the ASP.NET MVC project template, the class AccountController does not provide a DbContext property. A DbContext is passed as a parameter directly to the newly created UserManager instance by the default constructor. Unfortunately, UserManager does not provide access to the encapsulated DbContext.

To be able to access to the DbContext, I changed the AccountController to look like this:

[Authorize]
public class AccountController : Controller
{
  private ApplicationDbContext DbContext { get; set; }

  public AccountController()
  {
    DbContext = new ApplicationDbContext();

    UserManager 
      = new UserManager<ApplicationUser>(
          new UserStore<ApplicationUser>(DbContext));
    }

// removed: public AccountController(UserManager userManager)

// the rest was left unchanged

Fill the Child Table

Now I was ready to add a new entry to the UserProfile table when a new user registers. The method AccountController.Register was changed like this:

[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task Register(RegisterViewModel model)
{
  if (ModelState.IsValid)
  {
    var user = new ApplicationUser() 
    { 
      UserName = model.UserName, 
      UserProfile = new UserProfile()
    };

    using (TransactionScope scope 
      = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
    {
      var result 
        = await UserManager.CreateAsync(user, model.Password);

      scope.Complete();

      if (result.Succeeded)
      {
        await SignInAsync(user, isPersistent: false);
        return RedirectToAction("Index", "Home");
      }
      else
      {
        AddErrors(result);
      }
    }
  }

  // If we got this far, something failed, redisplay form
  return View(model);
}

Creating the user is wrapped by a database transaction to make sure the user will be created completely or not at all. Because UserManager.CreateAsync is async, the TransactionScope needs to be created with TransactionScopeAsyncFlowOption.Enabled. Please notice that this option is only available for .NET Framework 4.5.1 or above. To use the class TransactionScope, a reference to System.Transaction needs to be added to the project.

The call to UserManager.CreateAsync is doing all the magic. It creates the records in the tables AspNetUsers and UserProfile. It also makes sure that reference between the tables is set properly, means it sets UserProfile.User_Id to the correct value.

Summary

I took the following steps to have my custom user profile data connected to the ASP.NET user table:

  • Add the child model class
  • Add a property of the new type to the existing parent class
  • Declare the principal end of association, i.e. add a OnModelCreating to the DbContext to define which class is parent, and which is child
  • Create the database tables using the Package Manager Console
  • Update the controller to be able to store and retrieve the additional data

Consuming the data is easy. Just access the corresponding property like this:

DateTime creationDate = user.UserProfile.CreationDate;

Links

MSDN Data Developer Center: Code First to a New Database

Stack Overflow: What does principal end of an association means in 1:1 relationship in Entity framework

Stack Overflow: Get TransactionScope to work with async / await

Entity Framework: Loading Related Entities

“Device Not Functioning” Exception on Invalid PrimaryLanguageOverride Value in Windows Store Apps

Oh, what a title for a post. The correct title is “‘A device attached to the system is not functioning. (Exception from HRESULT: 0x8007001F)’ Exception Occurs When Showing A TextBox and ApplicationLanguages.PrimaryLanguageOverride Is Set To An Invalid Value in Windows Store Apps on Windows 8.1“.

Symptom

Building the Factory Commander, I was using ApplicationLanguages.PrimaryLanguageOverride to set the culture-correct date and number formatting. This is how the implementation in App.OnLaunched looked like:

ApplicationLanguages.PrimaryLanguageOverride 
  = new GeographicRegion().CodeTwoLetter;

Unfortunately, I can’t recall where I found this approach.

The development of Factory Commander was started on Windows 8, where this approach worked well. But after upgrading the development machine to Windows 8.1, the Commander crashed whenever I tried to rename, copy, or move a single item.

I figured out that, whenever the apps wants to show a TextBox, an exception with the description “A device attached to the system is not functioning. (Exception from HRESULT: 0x8007001F)” was thrown. The exception did not contain any further information. Well, what kind of device is used by a TextBox that is not used by other common controls of a Windows Store app?

A newly created Windows Store app on the same machine, which did contain a TextBox only, did not threw this exception. Was the Commander not compatible with Windows 8.1? I tested it on a machine having Windows 8.1 initially installed, so no upgrade was made: no problem! Did the upgrade corrupted the development machine?

Then I installed the Commander on a Windows RT device that was upgraded to Windows 8.1: no problem! Was it an issue with upgrading the x64 version of Windows 8? That seems to be the fact, because on another x64 machine that was upgraded to Windows 8.1, the same problem occurs. So I installed Windows 8 x64 on a new virtual machine, upgraded it to Windows 8.1: no problem.

The Reason

As you might assume from the description above, it took me some time to figure out what the cause was. The exception thrown was not really helpful – in other words: absolutely misleading – and the fact that the implementation worked fine on Windows 8, but partially did not on Windows 8.1, wasn’t helpful too. At least the “good” old step-by-step comparison approach made it.

Looking at the docs, ApplicationLanguages.PrimaryLanguageOverride expects a BCP-47 language tag. Valid values are for example “en”, “en-US”, “de”, “de-DE”, and so forth. The Commander set the value to GeographicRegion.CodeTwoLetter, which “… returns the two-letter ISO 3166-1 alpha-2 code for this region“.

If you are lucky, the region’s ISO code will match to the (or at least one) BCP-47 language code. In case you have the region set to “United States” (search for “region and language”), you do not have luck. The return value of GeographicRegion.CodeTwoLetter is “US”, which does not seem to be a valid BCP-47 code.

The Solution

I completely removed the setting of ApplicationLanguages.PrimaryLanguageOverride. The docs mention that “the … setting is persisted between sessions“. Means, the app needs to be uninstalled to have the change take effect.

To format the date and number values according to the user’s regional settings, I am using the CultureInfo of the user’s first configured language now. I was not able to figure out how to get the date and time formatting settings from the system.

// Get all installed languages
IReadOnlyList<string> languages 
  = Windows.System.UserProfile.GlobalizationPreferences.Languages;

// In case we have at least one, set the culture info from it.
// The result will be used later on as parameter 
// of String.Format calls.
CultureInfo = languages.Count > 0 
  ? new CultureInfo(languages[0])
    : CultureInfo.DefaultThreadCurrentUICulture;

I think there should be one language defined at minimum, but who knows what might happen.

Advertisement Side Effects

A side effect of the change was that the Microsoft advertising services started to deliver ads. Before the change, I was wondering why the fill rate (quota number of items delivered by number of requests) was exactly zero. I.e. no ad was delivered at all.

After the change, ads were retrieved. This means that the app’s primary language is used to request ads in the matching language. And having an invalid language set, there will be no advertisement.

Expected Behavior

Letting the user of an API set invalid values without giving any feedback is not really helpful from my point of view.

What I expect from ApplicationLanguages.PrimaryLanguageOverride is to throw an ArgumentOutOfRangeException in case I try to set an invalid value. This would have saved me a lot of time.

It throws an ArgumentException telling the value does not fall within the expected range when I try to set it to a value like “abcd”. But as long as the format of the value matches to the BCP-47 language tag structure, like “ab” or “ab-cd”, no exception is thrown by the setter.

Try It Yourself

Are you curious and want to try it yourself? This is how I was able to reproduce the behavior:

  • Use Windows 8.1
  • Create a Blank Windows Store App, name it as you like (e.g. PrimaryLanguageOverrideTest)
  • Add ApplicationLanguages.PrimaryLanguageOverride = "US"; as the first line of App.OnLaunched
  • Insert <TextBox> into the Grid of MainPage.xaml
  • Start the app in debug mode (press F5)

This will cause the app to crash with the exception described above.

To make the positive test, follow these steps:

  • Uninstall the app (search for it, right-click, choose uninstall)
  • Change ApplicationLanguages.PrimaryLanguageOverride = "US"; to ApplicationLanguages.PrimaryLanguageOverride = "en-US";
  • Start the app in debug mode (press F5)

The app should start now without any problems.

Links

ApplicationLanguages.PrimaryLanguageOverride

BCP-47 language tag

WinRT apps and Regional settings. The correct way to format dates and numbers based on the user’s regional settings?

Use Publicize.exe to Create Private Accessors for Visual Studio 2012+

Preface

Starting with Visual Studio 2012, private accessors cannot be created any more by the IDE. The post Home-made Private Accessor for Visual Studio 2012+ presents an approach on how to create private accessors using the class Microsoft.VisualStudio.TestTools.UnitTesting.PrivateObject.

Axel Mayer noted in the MSDN forums post How to create private accessors in VS 2012 that one can use the command line tool publicize.exe to create private accessors too.

Usage Of Publicize.exe

The usage of publicize.exe is quite simple. Open a command prompt, or a “VS2013 x86 Native Tools Command Prompt” to have the search path already set up, and run publicize.

In case you do not have the path set up correctly, the tool can be found at %Program Files (x86)%\Microsoft Visual Studio 11.0\Common7\IDE for Visual Studio 2012 or %Program Files (x86)%\Microsoft Visual Studio 12.0\Common7\IDE for VS 2013. At least, the tool is located there for the Ultimate edition of Visual Studio. I can’t tell which other editions contain it. Just have a look.

For a complete reference please refer to Using Publicize to Create a Private Accessor.

The usage in short: publicize.exe [options] input-assembly

The created assembly needs to be referenced by the test project. Of course, the source assembly – the assembly containing the classes to be tested – has to be referenced by the test project too.

publicize.exe creates classes named NameOfTheSourceClass_Accessor. In case the class to be tested is called MyClass, the accessor is named MyClass_Accessor.

publicize did work well for .NET 4.0 and .NET 4.5 assemblies in my tests. It also covered async and static methods.

Limitations

The docs mention that publicize does not support delegates or events.

From my tests I can add another limitation: publicize does not support Windows Store app assemblies (or I was not able to use it correctly). Running it against such an assembly I received these error messages (and a few more of the same type):

Cannot resolve dependency to Windows Runtime type ‘Windows.UI.Xaml.Application’. When using the ReflectionOnly APIs, dependent Windows Runtime assemblies must be resolved on demand through the ReflectionOnlyNamespaceResolve event.

Cannot resolve dependency to assembly ‘System.Runtime, Version=4.0.10.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a’ because it has not been preloaded. When using the ReflectionOnly APIs, dependent assemblies must be pre-loaded or loaded on demand through the ReflectionOnlyAssemblyResolve event.

Maybe you can give a hint on how this can be resolved. If so, please add a comment below. Thanks!

Resumé

As long as I don’t need accessors for Windows Store app assemblies, the usage of publicize.exe is my preferred way to generate private accessors.

In case publicize.exe does not support the source assembly type, I will created the private accessor myself as described by Home-made Private Accessor for Visual Studio 2012+.

Links

Home-made Private Accessor for Visual Studio 2012+

How to create private accessors in VS 2012

publicize.exe documentation

IsTabStop Changes ListView ‘s Focusable Behaviour in Windows Store Apps

The Issue

Using the Factory Commander, I noticed some strange behavior.

I opened a folder with more items than can be displayed on the screen on the left side. Then I scrolled to the last item of the list and switched to the right list. There, I moved up or down one folder level (goto parent or child folder). The item list on the right side gets refreshed, and, to my surprise, the list on the left side scrolled up. It did so every time I moved up or down one level until the first item of the left list was displayed. Switch back to the left list, the list scrolls down to the focused last item itself.

I was able to reproduce this behavior with a simple Windows Store app having just two ListView controls, without any additional logic. So it seems to be a general issue, independent from the Factory Commander implementation.

The Solution

It took me some time, but after a while I found the (or one of the possible) solution. By default, the IsTabStop property of a ListView is set to false. Changing it to true solved my issue. It seems that setting this property enables the ListView to keep the focus even if there are no items in the list.

In WPF, there are two different properties: Focusable and IsTabStop.

Focusablegets or sets a value that indicates whether the element can receive focus“, while IsTabStopgets or sets a value that indicates whether a control is included in tab navigation.

The Control (base class of ListView) in WPF contains both properties, while the Control implementation for Windows Store apps lacks of the Focusable property. Seems the “.NET for Windows Store apps” framework team at MS decided that this property is “not related to developing Windows Store apps”.

Links

2,000 Things You Should Know About WPF; explanation of Focusable and IsTabStop in WPF

Position the PopupMenu for Drag And Drop Operations in Windows Store Apps

Preface

Sometimes it is helpful to open a PopupMenu when the user drops items on a destination, e.g. to ask the user if the items should be copied or moved.

I’d like to open the PopupMenu exactly where the user released the mouse / finger, means put the upper left corner to this point on the screen.

The DragEventArgs, passed by the Drop event, do not provide the absolute coordinates, but the drop point that is relative to an UIElement.

Get the Position of a UIElement

Having the relative position of the drop point, we just need the absolute position of an UIElement – i.e. the drop destination, e.g. a ListView – to be able to calculate the absolute position of the PopupMenu.

Unfortunately, UIElement does not have a Position property or a GetPosition method. But it offers a method to “return a transform object that can be used to transform coordinates from the UIElement to the specified object“: UIElement.TransformToVisual.

To be honest, from reading the docs I would not have found out how to get the absolute position of a control. Because the docs do not mention that it is possible to pass null as a parameter.

The MSDN Context Menu Sample helped me out. Using this sample, I created an extension method for UIElement:

/// <summary>
/// Returns the position of the element.
/// </summary>
/// <param name="instance">The instance to be used.</param>
/// <returns>The position of the element.</returns>
public static Point GetPosition
  (
  this UIElement instance
  )
{
  // Return the position.
  return (instance.TransformToVisual(null)
          .TransformPoint(new Point()));
}

Add a Little Helper

Now that we have the absolute position of the drop destination, we just need to add the relative position of the drop point to the get the place where to open the PopupMenu.

Because Point does not offer an add operator, I created another extension method to keep the code tidy:

/// <summary>
/// Add the summand to the point.
/// </summary>
/// <param name="instance">The instance to be used.</param>
/// <param name="summand">The summand to be added.</param>
/// <returns>A new instance with the sum.</returns>
public static Point Add
  (
  this Point instance,
  Point summand
  )
{
  // Add the coordinates.
  return (new Point(instance.X + summand.X, instance.Y + summand.Y));
}

Use the Extentions

Using these extensions, the handling of the Drop event of a ListView and positioning of the PoupMenu at the drop point might look something like this:

private async void OnListViewDropAsync
  (
  object sender,
  DragEventArgs args
  )
{
  // The sender has to be a UIElement
  UIElement uiElement = sender as UIElement;

  if (uiElement == null)
  {
    return;
  }
  
  // Get the drop point in relation to the sender
  Point relativeDropPoint = args.GetPosition(uiElement);

  // Calculate the absolute position of the popup, 
  // using the extensions
  Point dropPoint = uiElement.GetPosition().Add(relativeDropPoint);

  // Create a popup
  PopupMenu menu = new PopupMenu();
  menu.Commands.Add(new UICommand("Copy"));
  menu.Commands.Add(new UICommand("Move"));
  menu.Commands.Add(new UICommand("Cancel"));

  // Show it at the drop point
  await menu.ShowAsync(dropPoint);

  // Do something depending on the user's selection.
}

Links

Context Menu Sample

Considerations Regarding Building a FileSystemWatcher for Windows Store Apps

Preface

Unfortunately, .NET for Windows Store apps does not provide a FileSystemWatcher class. Nevertheless, one might want get notified when a folder, or file in a folder, has been changed.

This post presents some points I found worth to consider when I implemented a FileSystemWatcher for Windows Store apps.

Because the implementation of such a class depends on the kind of application it is used by, there is no code sample provided. The intention of this post is to give you some ideas about what I think should be considered when creating your own FileSystemWatcher.

Receive Notifications

This is the easy part. You just have to create a StorageFolderQueryResult, add a handler to its ContentsChanged event, and execute the query.

...

private StorageFolderQueryResult QueryResult { get; set; }

...

protected override async void OnNavigatedTo
  (
  NavigationEventArgs args
  )
{
  QueryResult = KnownFolders.PicturesLibrary
    .CreateFolderQueryWithOptions(new QueryOptions() 
      { FolderDepth = FolderDepth.Shallow });

  QueryResult.ContentsChanged += OnFolderContentChanged;

  try
  {
    await QueryResult.GetFoldersAsync(0, 1);
  }
  catch (Exception)
  {
    ...
  }
}
…
private void OnFolderContentChanged
  (
  IStorageQueryResultBase sender,
  object args
  )
{
  // Do something
}

It is sufficient to get just one folder. There is no linkage between the notifications and the number of items retrieved by the query. Calling GetFoldersAsync(0, 1) keeps the runtime impact to a minimum.

You can also call another method of StorageFolderQueryResult. The important thing is that the query executes at all.

Notification Content

The “content” of the notification is the notification itself and the folder that might have changed. Why “might”? Have a look below.

No. There is no further information sent by the event. You only get notified that something has changed. You do not get any information about what has changed.

Double Notification

At the time of writing, it seems that Windows 8 is not consistent in the way it fires the event.

In case a file is changed, one event is fired.

But in case a folder is changed (or created or deleted), two events are fired, with a timespan of one second. The timespan was observed on Windows 8 x64, Windows 8.1 x64, and Windows 8 RT. So it seems to be hardware-and OS-independent. For the latest news on this, please refer to StorageFolderQueryResult.ContentsChanged Fires Twice.

Notification Aggregation

In case many changes are made to the file system in a very short time – e.g. the user selects 100 files by the file explorer and deletes them – the behavior is unpredictable. I observed at minimum one event, but very often two, sometimes the second one with a delay of several seconds, sometimes even more events.

Notifications About Changes in Child Folders

As you can see from the code snipped above, I set the QueryOptions.FolderDepth to FolderDepth.Shallow. This means I only want to monitor changes of the given folder. I don’t care about changes in its child folders.

Unexpectedly, I also received notifications when the content of a child folder has changed. E.g. I was monitoring the Folder “Parent”, which contains a folder names “Child”. Creating a folder name “Grandchild” in the folder “Child” also fires an event, although I am monitoring “Parent”, not “Child”. Changing the content of “Grandchild” does not trigger an event.

Discover the Changes

Because the event does not give any information about what has changed, you need to discover it yourself.

To do so, the content of the observed folder prior to the change is needed, and the content after the change is needed too. This sounds simple, but there are some details to pay attention to.

Time Matters

To get the current content of a folder, I found no other way but to call StorageFolder.GetItemsAsync (or one of it variants to retrieve folders and files, GetFoldersAsync and GetFilesAsync).

Calling StorageFolder.GetItemsAsync() on my C:\Windows\System32 folder takes more than four seconds for ~3,100 items (Directory.GetFileSystemEntries took 0.1 second [100 milliseconds]). Four seconds are an eternity on a computer. Lots of additional changes might happen while I am trying to retrieve the current state. And in addition, one second after the first notification the duplicate will be fired, but nothing has changed.

Abort Content Retrieval

So there is the need to somehow be able to abort the retrieval of the current content list, in case a real additional change occurred.

I implemented this by reading the content in small chunks. StorageFolder offers methods to read items chunk wise. Between reading a chunk, I check a flag that is set when a new change occurred. If that flag is set, reading the content is aborted and restarted.

Reading the items chunk wise had no impact on the overall time required to retrieve the content of a folder.

Ignore the Double Notification

How can you tell if the current notification is a new one or the duplicate of the last? And what to do if there is a change 800 milliseconds after the last one occurred, but the notification duplicate has not arrived?

I can’t tell. That’s because the event does not give me any information about what has changed. In my app, I decided to ignore all additional notifications that were sent in less than a second after the “initial” notification was retrieved.

How to Compare the Content?

The list returned by StorageFolder.GetItemsAsync contains the folders first, and then the files. Trying to find differences by comparing the name only will fail, because the name of a folder should not be compared to the name of a file.

The consequence is to have the content lists separated by folders and files, or to find another way to make sure a folder is not compared to a file and vice versa.

It is also worth to mention that the list returned by StorageFolder.GetItemsAsync, and the folder / file variants, is sorted in natural sort order. I found C# comparison implementations on Stack Overflow.

Depending on what your app uses, comparing the name to detect changes might not be sufficient. In case the app relies on the file’s size or the last modified date too, there is additional code to be written, because these attributes needs to be collected in a second step (see Discover Properties of Storage Items in Windows Store Apps).

Conclusion

Creating a FileSystemWatcher for Windows Store apps is heavy stuff from my point of view. Even though I found a way to handle all the ‘challenges’, I do not really feel happy with my solution.

In case you have an approach that you think works good, please feel free to share it with us.

Links

NET for Windows Store apps

StorageFolderQueryResult documentation

StorageFolderQueryResult.ContentsChanged Fires Twice

Natural Sort Order

Natural sort order C# implementations

Discover Properties of Storage Items in Windows Store Apps