Category Archives: Short Walks

Short Walks – NSubstitute extension methods like .Received() can only be called on objects created using Substitute.For() and related methods

Not a huge post, but this has tripped me up several times, and sent me down some quite deep rabbit holes.

On to the story…

I once had a check to received calls like this:

var myData = Substitute.For<IData>();

. . .

myData
    .Add(Arg.Is<MyEntity>(a =>
        a.Active == true
        && a.Field1 == 1
        && a.Field2 == 42))
    .Received(1);

And I was getting the error:

NSubstitute extension methods like .Received() can only be called on objects created using Substitute.For() and related methods

I was confident that I had declared it correctly, a few lines above… I could, in fact see that I had declared it correctly. As my brain slowly dribbled from my nose, I did a quick search on the web; and found a solitary article that suggested I might have confused the Received and method calls; the correct syntax being:

myData
    .Received(1)
    .Add(Arg.Is<MyEntity>(a =>
        a.Active == true
        && a.Field1 == 1
        && a.Field2 == 42));

Hopefully, now that I’ve doubled the available resources available to people finding this error, it will plague me less in compensation.

Short Walks – System.InvalidOperationException: ‘The seed entity for entity type ‘MyEntity’ cannot be added because another seed entity with the same key value for {‘Id’} has already been added. Consider using ‘DbContextOptionsBuilder.EnableSensitiveDataLogging’ to see the conflicting key values.’

I got this error recently while playing with EF Core 2. There’s very little on Google about it; although it’s not a hugely difficult problem to solve, if I ever get it again, I can just Google it !

The error:

System.InvalidOperationException: ‘The seed entity for entity type ‘MyEntity’ cannot be added because another seed entity with the same key value for {‘Id’} has already been added. Consider using ‘DbContextOptionsBuilder.EnableSensitiveDataLogging’ to see the conflicting key values.’

If effectively cause by a conflict in the primary key; and it gives you the first step towards solving it in the error (in OnModelCreating):

var options =
    new DbContextOptionsBuilder<ApplicationDbContext>()
         .UseSqlServer(configuration.GetConnectionString("DefaultConnection"))
         .EnableSensitiveDataLogging()
         .Options;

Now it says:

System.InvalidOperationException: ‘The seed entity for entity type ‘MyEntity’ cannot be added because another seed entity with the key value ‘Id:1′ has already been added.’

In my particular case, I’d been playing around with adding some seed data, and had left this in (OnModelCreating):

modelBuilder.Entity<MyEntity>().HasData(new Data.MyEntity()
{
    Id = 1,
    Name = "Test",
    CreatedDate = new DateTime(2018, 07, 03),
    UpdatedDate = new DateTime(2018, 07, 03)
});

Short Walks – XUnit Warning

As with many of these posts – this is more of a “note to self”.

Say you have an assertion that looks something like this in your Xunit test:

Assert.True(myEnumerable.Any(a => a.MyValue == "1234"));

In later versions (not sure exactly which one this was introduced it), you’ll get the following warning:

warning xUnit2012: Do not use Enumerable.Any() to check if a value exists in a collection.

So, Xunit has a nice little feature where you can use the following syntax instead:

Assert.Contains(myEnumerable, a => a.MyValue == "1234");

Short Walks – Submit a single row of data in ReactJS

While looking into the react sample app, I came across a scenario whereby you might need to pass a specific piece of data across to an event handler. A lot of the online examples cover data state; but what happens when you have a situation such as the one in the sample app; consider this:

In this instance, you want to pass the temperature of the line you’ve selected. The solution is quite simple, and documented here:

private renderForecastsTable(forecasts: WeatherForecast[]) {
    return <table className='table'>
        <thead>
            <tr>
                <th>Date</th>
                <th>Temp. (C)</th>
                <th>Temp. (F)</th>
                <th>Summary</th>
            </tr>
        </thead>
        <tbody>
        {forecasts.map(forecast =>
            <tr key={ forecast.dateFormatted }>
                <td>{ forecast.dateFormatted }</td>
                <td>{ forecast.temperatureC }</td>
                <td>{ forecast.temperatureF }</td>
                <td>{forecast.summary}</td>
                <td><button onClick={(e) => this.handleClick(e, forecast)}>Log Temperature!</button></td>
            </tr>
        )}
        </tbody>
    </table>;
}

Here, we’re passing the entire forecast object to the handler; which looks like this:

handleClick = (event: React.FormEvent<HTMLButtonElement>, forecast: WeatherForecast) => {
    console.log("timestamp: " + event.timeStamp);
    console.log("data: " + forecast.temperatureC);
}

https://reactjs.org/docs/forms.html

https://reactjs.org/docs/handling-events.html

Short Walks – Using AppSettings.json in Asp Net Core

One of the things that is very different when you move to Asp.Net Core is the way that configuration files are treated. This partly comes from the drive to move things that are not configuration out of configuration files. It looks like the days of app.config and web.config are numbered and, in their place, we have AppSettings.Json. Here’s an example of what that new file might look like:

{
  "Logging": {
    "LogLevel": {
      "Default": "Warning"
    }
  },
  "AzureAppSettings": {
    "ApplicationInsightsKey": "1827374d-1d50-428d-92a1-c65fv2d73272"
  }
 
}
 

The old files were very flat and, using the configuration manager, you could simply read a setting; something like this:

var appSettings = ConfigurationManager.AppSettings;
string result = appSettings[key];

So, the first question is: can you still do this? The answer is, pretty much, yes:

public void ConfigureServices(IServiceCollection services)
{            
    IConfigurationBuilder builder = new ConfigurationBuilder()
          .SetBasePath(Directory.GetCurrentDirectory())
          .AddJsonFile("appsettings.json");
    Configuration = builder.Build();

    Configuration["AzureAppSettings:ApplicationInsightsKey"]

However, you now have the option of creating a class to represent your settings; something like:

AzureAppSettings azureAppSettings = new AzureAppSettings();
Configuration.GetSection("AzureAppSettings").Bind(azureAppSettings);

If you use this approach then you’ll need an extension library from NuGet:

Install-Package Microsoft.Extensions.Configuration.Binder

Is it better, or worse?

At first glance, it would appear that things have gotten worse; or at least, more complex. However, the previous method had one massive problem: it was a static class. The result being that most people have written their own wrapper around the ConfigurationManager class. We now have a class that can be injected out of the box; alternatively, you can split your configuration up into classes, and pass the classes around; the more I think about this, the better I like it: it makes more sense to have a class or method accept parameters that are necessary for its execution and, arguably, breaks the single responsibility principle if you’re faffing around trying to work out if you have all the operating parameters.

The other advantage here is that the configuration file can now be hierarchical. If you have well designed, small pieces of software then this might not seem like much of an advantage, but if you have 150 settings in your web.config, it makes all the difference.

Short Walks – C# Pattern Matching to Match Ranges

Back in 2010, working at the time in a variety of languages, including VB, I asked this question on StackOverflow. In VB, you could put a range inside a switch statement, and I wanted to know how you could do that in C#. The (correct) answer at the time was that you can’t.

Fast forward just eight short years, and suddenly, it’s possible. The new feature of pattern matching in C# 7.0 has made this possible.

You can now write something like this (this is C# 7.1 because of Async Main):

static async Task Main(string[] args)
{            
    for (int i = 0; i <= 20; i++)
    {
        switch (i)
        {
            case var test when test <= 2:
                Console.WriteLine("Less than 2");
                break;
 
            case var test when test > 2 && test < 10:
                Console.WriteLine("Between 2 and 10");
                break;
 
            case var test when test >= 10:
                Console.WriteLine("10 or more");
                break;
        }
 
        await Task.Delay(500);
    }
 
    Console.ReadLine();
}

References

https://docs.microsoft.com/en-us/dotnet/csharp/pattern-matching

https://visualstudiomagazine.com/articles/2017/02/01/pattern-matching.aspx

Short Walks – Entity Framework – Exception calling “SetData” with “2” argument(s)

The full exception is a little more verbose, but not much more helpful:

Exception calling “SetData” with “2” argument(s): “Type ‘Microsoft.VisualStudio.ProjectSystem.VS.Implementation.Package.Automation.OAProject’ in assembly
‘Microsoft.VisualStudio.ProjectSystem.VS.Implementation, Version=15.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a’ is not marked as serializable.”
At C:\myapp\packages\EntityFramework.6.2.0\tools\EntityFramework.psm1:722 char:5
+ $domain.SetData(‘startUpProject’, $startUpProject)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : SerializationException

System.NullReferenceException: Object reference not set to an instance of an object.
at System.Data.Entity.Migrations.Extensions.ProjectExtensions.GetProjectTypes(Project project, Int32 shellVersion)
at System.Data.Entity.Migrations.Extensions.ProjectExtensions.IsWebProject(Project project)
at System.Data.Entity.Migrations.MigrationsDomainCommand.GetFacade(String configurationTypeName, Boolean useContextWorkingDirectory)
at System.Data.Entity.Migrations.UpdateDatabaseCommand.<>c__DisplayClass2.<.ctor>b__0()
at System.Data.Entity.Migrations.MigrationsDomainCommand.Execute(Action command)

When does it happen?

Typically, you get it when you’re trying to do a EF operation, for example:

Update-Database

But your start-up project does not have an app.config or web.config file that has a connection string pointing to that database.

Why does it happen?

EF looks in your start-up project to find your web.config and work out where your database is. Clearly this could be a slightly better worded error.

Short Walks – XUnit Tests Not Appearing in Test Explorer

On occasion, there may be a case where you go into Test Explorer, knowing that you have XUnit tests within the solution; the Xunit tests are in a public class, they are public, and they are decorated correctly (for example, [Fact]). However, they do not appear in the Text Explorer.

If you have MS Test tests, you may find that they do appear in the Test Explorer – only the XUnit tests do not.

Why?

To run Xunit tests from the command line, you’ll need this package.

To run Xunit tests from Visual Studio, you’ll need this package.

References

https://xunit.github.io/docs/nuget-packages.html

Short Walks – Using CompilerService Arguments in an Interface

Until today, I thought that the following code would work:

class Program
{
    static void Main(string[] args)
    {
        ITest test = new Test();
        test.Log("testing");
        Console.ReadLine();
    }
}
 
interface ITest
{
    void Log(string text, string function = "");
}
 
class Test : ITest
{
    public void Log(string text, [CallerMemberName] string function = "")
    {
        Console.WriteLine($"{function} : text");
    }
}

And, by work, I mean output something along the lines of:

Main : testing

However; it actually outputs:

: testing

CompilerServiceAttributes need to be on the Interface, and not on the implementation

class Program
{
    static void Main(string[] args)
    {
        ITest test = new Test();
        test.Log("testing");
        Console.ReadLine();
    }
}
 
interface ITest
{
    void Log(string text, [CallerMemberName] string function = "");
}
 
class Test : ITest
{
    public void Log(string text, string function = "")
    {
        Console.WriteLine($"{function} : text");
    }
}

Why?

When you think about it, it does kind of make sense. Because you’re calling against the interface, the compiler injected value needs to be there; if you took the interface out of the equation, then the attribute needs to be on the class.

You live and learn!

Short Walks – Error: could not find dependent assembly

Error: could not find dependent assembly ‘System.Runtime, Version=4.1.1’

This error can occur when you have conflicting versions of a system (or any) assembly. The following is a .Net Framework feature that will redirect the assemblies to be the same, and thereby resolve the conflict:

      <dependentAssembly>
        <assemblyIdentity name="System.Reflection" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-4.1.1.0" newVersion="4.3.0" />
      </dependentAssembly>