Entity Framework Pitfalls: Queries Over Navigation Properties When There Are Foreign Key Properties Are Ignored

Long title, I know! Smile

Another one for Entity Framework Code First. The problem is: imagine you have an entity with a relation to another entity (one-to-one, many-to-one) where you have both the navigation property and the foreign key property:

public class Source
{
public int Id { get; set; }

[ForeignKey("TargetId")]
public virtual Target Target { get; set; }

public int? TargetId { get; set; }
}

public class Target
{
public int Id { get; set; }
public virtual ICollection<Source> Sources { get; set; }
}

You may want to query all Sources that have a Target set:

var sourcesWithTarget = ctx
.Sources
.Where(source => source.Target != null)
.ToList();

However, you will get this SQL instead:

SELECT [Extent1].[Id] AS [Id], [Extent1].[TargetId] AS [TargetId], 
FROM [dbo].[Source] AS [Extent1]

See? No WHERE clause!

If, instead, we query on the foreign key property:

var sourcesWithTarget = ctx
.Sources
.Where(source => source.TargetId != 0)
.ToList();

Then we get what we want:

SELECT [Extent1].[Id] AS [Id], [Extent1].[TargetId] AS [TargetId], 
FROM [dbo].[Source] AS [Extent1]
WHERE 0 <> [Extent1].[TargetId]

Weird, huh?

Stay tuned for more!

Missing Features in Entity Framework Core

Updated: with EF Core 1.1 and 2.0.

Here’s a brief summary of some of the features that were present in previous versions of Entity Framework (6.x) and were excluded (or are not yet implemented) in Entity Framework Core 2.0:

Feature Description Reason/Workaround
Entity Type Configuration The ability to load entity configuration from classes in the same assembly as the context (EntityTypeConfiguration)

https://github.com/aspnet/EntityFramework/issues/2805

Implemented in EF Core 2.0.

Lazy loading The ability to load entity relations after the root entity was loaded, automatically

Will be available in a future version. For now, we need to use eager loading (Include).

https://github.com/aspnet/EntityFramework/issues/3797

Explicit loading The ability to load entity relations after the root entity was loaded, explicitly

https://github.com/aspnet/EntityFramework/issues/3797

Implemented in EF Core 1.1.

Support for Group By Specifying GroupBy in a LINQ query

Currently it falls back silently to LINQ to Objects, meaning, brings everything from the database and groups in memory. Will be available in a future version. For now, use plain SQL.

https://github.com/aspnet/EntityFramework/issues/2341

Support for user defined functions

Using static methods as UDFs

https://github.com/aspnet/EntityFramework/issues/4319

Implemented in EF Core 2.0.

DateTime, TimeSpan operations and common SQL functions Doing DateTime operations and using common SQL functions in LINQ

The ability to do queries involving Date/Time operations (DbFunctions) and common SQL functions (SqlFunctions) in LINQ queries is not supported now. Will be available in a future version.

https://github.com/aspnet/EntityFramework/issues/2850

https://github.com/aspnet/EntityFrameworkCore/issues/6025

Complex Values Support for properties of complex types (value objects)

https://github.com/aspnet/EntityFramework/issues/246

Implemented in EF Core 2.0.

Many to Many Collections Many-to-many relations without a middle entity/table

Will be available in a future version. For now, we need a middle entity and table.

https://github.com/aspnet/EntityFramework/issues/1368

Table Splitting

https://github.com/aspnet/EntityFramework/issues/619

Implemented in EF Core 2.0.

Table Per Type Inheritance Strategy

Will be available in a future version.

https://github.com/aspnet/EntityFramework/issues/2266

Table Per Concrete Type Inheritance Strategy

Will be available in a future version.

https://github.com/aspnet/EntityFramework/issues/3170

Mapping CUD with stored procedures The ability to use stored procedures for doing inserts, updates and deletes seemlesly

Will be available in a future version.

https://github.com/aspnet/EntityFramework/issues/245

Map database views The ability to map views instead of tables

Will be available in a future version.

https://github.com/aspnet/EntityFramework/issues/1679

https://github.com/aspnet/EntityFramework/issues/827

Spatial data types The ability to query and use spatial data types

Will be available in a future version.

https://github.com/aspnet/EntityFramework/issues/1100

Custom conventions The ability to add custom conventions

Will be available in a future version.

https://github.com/aspnet/EntityFramework/issues/214

Populate non-model types from SQL Turn the results of custom SQL into classes that are not part of the model

Will be available in a future version.

https://github.com/aspnet/EntityFramework/issues/240

Connection resiliency support The ability to retry connecting and sending queries

https://github.com/aspnet/EntityFramework/issues/237

Implemented in EF Core 1.1.

Seeding data in migrations The ability to add data when migrating

Will be available in a future version.

https://github.com/aspnet/EntityFramework/issues/629

Command and query interception The ability to intercept queries and SQL commands

Will be available in a future version.

https://github.com/aspnet/EntityFramework/issues/626

https://github.com/aspnet/EntityFramework/issues/4048

https://github.com/aspnet/EntityFramework/issues/737

Visual Studio support for generating/updating entities from the database and viewing the model The ability to generate the model from the database from inside Visual Studio and to view the model graphically

Will be available in a future version.

https://github.com/aspnet/EntityFramework/issues/5837

Database initializers Database initializers Dropped.
Automatic migrations Automatic migrations Dropped.
Pluralization Service Pluralization Service

https://github.com/aspnet/EntityFramework/issues/2506

Implemented in EF Core 2.0.

ObjectContext events SavingChanges and ObjectMaterialized events of ObjectContext

Will be available in a future version.

https://github.com/aspnet/EntityFramework/issues/3204

https://github.com/aspnet/EntityFrameworkCore/issues/626

ObjectContext (Entity SQL) Entity SQL Dropped.
Model first approach Model first approach Dropped.
Data Annotations validations The ability to perform data annotations validations before saving changes Dropped.
Support for System.Transactions The ability to use TransactionScope and distributed transactions

Will be available in a future version.

https://github.com/aspnet/EntityFrameworkCore/issues/5595

Please let me know if you think I missed something! Winking smile

See Microsof’t comparison of Core and pre-Core versions here: https://docs.microsoft.com/en-us/ef/efcore-and-ef6/features.

For the most up to date roadmap, please consult the EF Core roadmap: https://github.com/aspnet/EntityFramework/wiki/Roadmap.

Also, do check out the Entity Framework issue tracker: https://github.com/aspnet/EntityFramework/issues

Implementing Missing Features in Entity Framework Core – Part 5: Getting the SQL for a Query

This will be the fifth post in a series of posts about bringing the features that were present in Entity Framework pre-Core into EF Core. The others are:

  • Part 1: Introduction, Find, Getting an Entity’s Id Programmatically, Reload, Local, Evict

  • Part 2: Explicit Loading

  • Part 3: Validations

  • Part 4: Conventions

This time I’m going to talk about something that is often requested: how can I get the SQL string for a LINQ query? If you remember, in the pre-Core days you had to do some reflection in order to get the underlying ObjectQuery and then call its ToTraceString method. Now, things are very different, although I may say, still rather tricky!

So, this is all we need:

private static readonly TypeInfo QueryCompilerTypeInfo = typeof(QueryCompiler).GetTypeInfo();
private static readonly FieldInfo QueryCompilerField = typeof(EntityQueryProvider).GetTypeInfo().DeclaredFields.First(x => x.Name == "_queryCompiler");
private static readonly PropertyInfo NodeTypeProviderField = QueryCompilerTypeInfo.DeclaredProperties.Single(x => x.Name == "NodeTypeProvider");
private static readonly MethodInfo CreateQueryParserMethod = QueryCompilerTypeInfo.DeclaredMethods.First(x => x.Name == "CreateQueryParser");
private static readonly FieldInfo DataBaseField = QueryCompilerTypeInfo.DeclaredFields.Single(x => x.Name == "_database");
private static readonly PropertyInfo DependenciesProperty = typeof(Database).GetTypeInfo().GetDeclaredProperty("Dependencies");

public static string ToSql<TEntity>(this IQueryable<TEntity> query) where TEntity : class
{
if (!(query is EntityQueryable<TEntity>) && !(query is InternalDbSet<TEntity>))
{
throw new ArgumentException("Invalid query");
}

var queryCompiler = (IQueryCompiler) QueryCompilerField.GetValue(query.Provider);
var nodeTypeProvider = (INodeTypeProvider) NodeTypeProviderField.GetValue(queryCompiler);
var parser = (IQueryParser) CreateQueryParserMethod.Invoke(queryCompiler, new object[] { nodeTypeProvider });
var queryModel = parser.GetParsedQuery(query.Expression);
var database = DataBaseField.GetValue(queryCompiler);
var dependencies = (DatabaseDependencies)DependenciesProperty.GetValue(database);
var queryCompilationContextFactory = dependencies.QueryCompilationContextFactory;
var queryCompilationContext = queryCompilationContextFactory.Create(false);
var modelVisitor = (RelationalQueryModelVisitor) queryCompilationContext.CreateQueryModelVisitor();
modelVisitor.CreateQueryExecutor<TEntity>(queryModel);
var sql = modelVisitor.Queries.First().ToString();

return sql;
}

You can see that it needs some reflection, meaning, things *may* break on a future version. I cached all of the fields to make the access faster in subsequent calls. For the time being, it works perfectly:

var sql1 = ctx.Blogs.ToSql();

var sql2 = ctx
.Blogs
.Where(b => b.CreationDate.Year == 2016)
.ToSql();

Hope this is useful to you! Winking smile

Unit Testing .NET Core

Introduction

With the recent arrival of .NET Core, some things that we were used to having are no longer available. This includes unit tests – plus Visual Studio integration – and mocking frameworks. Fortunately, they are now becoming available, even if, in some cases, in pre-release form.

In this post, I will cover:

  • Unit testing frameworks
  • Mocking libraries
  • Validation libraries

I won’t explore everything that exists, just present a simple setup that works well for .NET Core.

Unit Testing

So, you want to do unit testing? There are a couple of frameworks for that purpose that work with .NET Core, which include:

MS Test is Microsoft’s own unit testing library, I’d say a much hated one because of its historical tie to Visual Studio. This was the last one that was announced for .NET Core and it’s still not in release form.

They more or less work the same way, so let’s see how to use xUnit, my favorite one So, you need to add two Nuget packages:

  • xunit: this is the actual library that you will be using
  • dotnet-test-xunit: this is the runner and integration with Visual Studio

I sometimes have a base class for tests, which takes care of loading configuration and initializing stuff, but let’s leave that aside. A unit test class for xUnit looks like this:

using Xunit;

public class MyTests
{
[Fact]
public void Test()
{
}
}

Now, you need to configure the runner so that you can run tests in Visual Studio. Using project.json, it goes like this:

{
"version": "1.0.0-*",
"testRunner": "xunit",
"buildOptions": {
"emitEntryPoint": false,
"copyToOutput": ["appsettings.json"]
},

"dependencies": {
"dotnet-test-xunit": "2.2.0-preview2-build1029",
"Microsoft.Extensions.Configuration": "1.0.0",
"Microsoft.Extensions.Configuration.Json": "1.0.0",
"Microsoft.Extensions.PlatformAbstractions": "1.0.0",
"Microsoft.NETCore.App": {
"type": "platform",
"version": "1.0.0"
},
"xunit": "2.2.0-beta2-build3300"
},

"frameworks": {
"netcoreapp1.0": {
"imports": "dnxcore50"
}
}
}

Notice that I am copying to the output folder the appsettings.json file, I am not going to talk about it, but let’s just say that it has some configuration that my tests will use, and it needs to be on the same file as the unit tests assembly.

With the Visual Studio integration working, we get this:

image

So we can run and debug our tests directly from here. Nice to have coherent behavior for all unit test frameworks!

Mocking

As for mocking, there are also some mocking frameworks that work with .NET Core:

I’ll pick Moq for this exercise. Just add the Moq package to your project. Here’s how to do simple mocking of an interface:

using Xunit;
using Moq;

[Fact]
public void Test()
{
var mock = new Mock<IService>();
mock
.Setup(x => x.Get())
.Returns("Hi there!");

var svc = mock.Object;

var result = svc.Get();

Assert.NotNull(result);

Assert.Equal("Hi there!", result);
}

Exactly the same as you’d do in a classic .NET unit test using mocking.

Validation

As for validations, I know of two libraries that work with .NET Core:

I’ll pick FluentAssertions. Here’s a simple example, for the same test:

using FluentAssertions;
using Moq;
using Xunit;

[Fact]
public void Test()
{
var mock = new Mock<IService>();
mock
.Setup(x => x.Get())
.Returns("Hi there!");

var svc = mock.Object;

var result = svc.Get();

result
.Should()
.BeOfType<string>()
.And
.Be("Hi there!");
}

Again, this should be familiar to everyone.

Conclusion

So, it’s no longer unit tests holding us back from .NET Core! Most of what is done today in classic .NET can be done in Core by now. There are still some more complex libraries, for interception, mapping, serialization, etc, that are not quite there yet, but I expect these to come with time.

Moving to ASP.NET MVC Core 1

Introduction

The new version of ASP.NET MVC, Core 1, brought a number of changes. Some were additions, but others were removals.The structure is similar and will be mostly familiar to anyone who has worked with ASP.NET MVC, but a few stuff is very different. Let’s visit all of them, in a lightweight way – more posts coming soon.

Unified API

MVC and Web API have been merged together, which is a good thing. The new API is based on OWIN. There is a single Controller base class and an IActionResult serves as the base class for the responses, if we so want it – we can also return POCO objects.

Application Events

Application_Start and Application_End events are now gone, as is IRegisteredObject interface and HostingEnvironment.RegisterObject. If you want to be notified (and possibly cancel) hosting event, get a handle to the IApplicationLifetime instance using the built-in service provider and hook to the ApplicationStarted, ApplicationStopping or ApplicationStopped properties.

Dependency Injection

The dependency resolution APIs of both MVC and Web API has been dropped in favor of the new .NET Core mechanism, which is usually configured in the Startup class. You can plug your own IoC/DI framework as well. I wrote a post on this, which you can find here. There are now several new services that you can use to query information from the executing context, experienced users will perhaps find it complex. I’d say this is matter for a full post soon.

Routing

Attribute routing comes out of the box, no need to explicitly configure it. There is no global routing table (RouteTable.Routes), so we need to configure it in the Startup class, in the UseMvc method:

app.UseMvc(routes =>

{

    routes.MapRoute(

        name: "default",

        template: "{controller=Home}/{action=Index}/{id?}");

});

Route handlers (IRouteHandler) are not directly usable. Remember, route handlers are called when the route is matched. Instead, we need to use an IRoute:

public class MyRouter: IRouter

{

    private readonly IRouteHandler _handler;

 

    public MyRouter(IRouteHandler handler)

    {

        this._handler = handler;

    }

 

    public VirtualPathData GetVirtualPath(VirtualPathContext context)

    {

        return null;

    }

 

    public Task RouteAsync(RouteContext context)

    {

        context.Handler = this._handler.GetRequestHandler(context.HttpContext, context.RouteData);

 

        return Task.FromResult(0);

    }

}

Routes are added in Startup as well:

app.UseMvc(routes =>

{

    var routeBuilder = routes.MapRoute(

        name: "default",

        defaults: new {},

        template: "{controller=Home}/{action=Index}/{id?}");

 

    routeBuilder.DefaultHandler = new MyRouter();

});

There is already an handler so in this example we are overriding it. You better know what you’re doing if you are going to do something like this!

Route constraints (IRouteConstraint) are still available, just configured in a different way. These allow us to define if a route’s parameter should be matched:

services.Configure<RouteOptions>(options => options.ConstraintMap.Add("my", typeof(MyRouteConstraint)));

And then on the route template attribute we use the constraint:

[Route("home/action/{id:myconstraint}")]

Now there are also conventions (IApplicationModelConvention) that we can use:

public class MyConvention : IApplicationModelConvention

{

    public void Apply(ApplicationModel application)

    {

        //...

    }

}

Registration is done in the AddMvc method too:

services.AddMvc(options => options.Conventions.Insert(0, new MyConvention()));

Configuration

The Web.config file is gone, now configuration is done in a totally different way, preferably through JSON. You can either make the IConfigurationRoot instance available through the services collection:

public IConfigurationRoot Configuration { get; set; }

 

public void ConfigureServices(IServiceCollection services)

{

    //build configuration and store it in Configuration

 

    services.AddSingleton(this.Configuration);

 

    //...

}

or you can build a strongly typed wrapper class for the configuration. For example, for this JSON file:

{

    "ConnectionString": "Data Source=.;Integrated Security=SSPI; Initial Catalog=MyDb",

    "Timeout": 300

}

we could have this code:

class MySettings

{

    public string ConnectionString { get; set; }

    public int Timeout { get; set; }

}

 

public class Startup

{

    public IConfigurationRoot Configuration { get; set; }

    

    public void ConfigureServices(IServiceCollection services)

    {

        services.AddOptions();

        services.Configure<AppSettings>(this.Configuration);

 

        //...

    }

}

 

public MyController : Controller

{

    public MyController(IOptions<AppSettings> appSettings)

    {

        //...

    }

}

Public Folder

Now the public folder is not the same as the project folder: by default, there’s a wwwroot folder below the project folder which is where all the “physical” assets will be copied to at runtime.

Virtual Path Providers

Again, virtual path providers are gone, but there is a similar mechanism. You need to get a hold of the IHostingEnvironment instance and use or change its ContentRootFileProvider or WebRootFileProvider properties. There’s a new file provider interface, IFileProvider, that you can leverage to provide your own behavior:

public class MyFileProvider : IFileProvider

{

    public IDirectoryContents GetDirectoryContents(string subpath)

    {

        //...

    }

 

    public IFileInfo GetFileInfo(string subpath)

    {

        //...

    }

 

    public IChangeToken Watch(string filter)

    {

        //...

    }

}

If you do not wish to or cannot implement one of the IDirectoryContents, IFileInfo or IChangeToken, just return null.

The difference between ContentRootFileProvider and WebRootFileProvider is that the first is used for files inside IHostingEnvironment.ContentRootPath and the latter for those inside IHostingEnvironment.WebRootPath.

OWIN

MVC Core is now based on the OWIN standard, which means you can add your own middleware to the pipeline. This replaces both HTTP Modules and HTTP Handlers. OWIN middleware sits on the pipeline, like this:

public class MyMiddleware

{

    private readonly RequestDelegate _next;

 

    public MyMiddleware(RequestDelegate next)

    {

        this._next = next;

    }

 

    public async Task Invoke(HttpContext context)

    {

        await context.Response.WriteAsync("Hello from a middleware class!");

        await this._next.Invoke(context);

    }

}

We register middleware components in the IApplicationBuilder instance:

app.UseMiddleware<MyMiddleware>();

A middleware class is just a simple POCO class that follows two conventions:

  • The constructor receives a RequestDelegate instance
  • It has an Invoke method taking an HttpContext and returning a Task

The constructor can also take any service that is registered in the service provider. Pay attention, the order by which we add add our middleware has importance. Make sure you add yours soon enough to encapsulate whatever logic you wish to wrap.

Logging and Tracing

Logging and tracing is now only supported as part of the new unified logging framework. You can also write your own middleware that wraps the MVC processing and add your own logging logic. You gain access to the ILoggerFactory or ILogger/ILogger<T> instances through the service provider or using Dependency Injection:

public class MyController : Controller

{

    public MyController(ILogger<MyController> logger)

    {

    }

}

Custom Errors

The custom errors setting is also gone. In order to have similar behavior, enable developer exception page in the Startup class.

Controllers and Views

Controllers stay the same with one addition: we can have POCO controllers, that is, controllers that do not inherit from a base class (other than Object, that is). In order to make proper use of them, for example, if we want to access the context, we need to inject some properties into the controller class – the HttpContext.Current property is no more:

public class HomeController// : Controller

{

    //automatically injected

    [ActionBindingContext]

    public ActionBindingContext BindingContext { get; set; }

 

    //automatically injected

    [ViewDataDictionary]

    public ViewDataDictionary ViewData { get; set; }

 

    //automatically injected

    [ActionContext]

    public ActionContext ActionContext { get; set; }

 

    //constructor-set

    public IUrlHelper Url { get; private set; }

 

    public dynamic ViewBag

    {

        get { return new DynamicViewData(() => this.ViewData); }

    }

 

    public HomeController(IServiceProvider serviceProvider)

    {

        this.Url = serviceProvider.GetService(typeof(IUrlHelper)) as IUrlHelper;

    }

}

The serviceProvider instance will come from the ASP.NET MVC Core dependency injection mechanism.

In views, we now only have the Razor engine. We can now inject components into views:

@inject IMyClass MyClass

 

@MyClass.MyMethod()

and also define functions in the markup:

@functions {

    string MyMethod() {

        return "Something";

    }

}

Another new thing is the _ViewImports.cshtml file. Here we can specify stuff that will apply to all views. The following directives are supported:

  • addTagHelper
  • removeTagHelper
  • tagHelperPrefix
  • using
  • model
  • inherits
  • inject

Layouts files stay the same.

On the other hand, mobile views no longer exist. Of course, you can add logic to find if the current browser is mobile and then serve an appropriate view. Again, the Browser and IsMobileDevice properties are now gone (with the browser capabilities database), so you will have to do your own sniffing.

You can still add view engines (currently, only Razor is supported), you do that when you register MVC services (no more ViewEngines.Engines property):

services

    .AddMvc()

    .AddViewOptions(x =>

        {

            x.ViewEngines.Add(new MyViewEngine());

        });

Model validation providers used to be extensible through the IClientValidatable interface. Now, we have IClientModelValidatorProvider, and we need to add our providers to a collection also when we register MVC services:

services

    .AddMvc()

    .AddViewOptions(x =>

        {

            x.ClientModelValidatorProviders.Add(new MyClientModelValidationProvider());

        });

A client model validation provider needs to implement IClientModelValidatorProvider:

public class MyClientModelValidationProvider : IClientModelValidatorProvider

{

    public void CreateValidators(ClientValidatorProviderContext context)

    {

        //...

    }

}

Finally, views now cannot be precompiled. In the early days of ASP.NET MVC Core, it was possible to precompile them, but not anymore.

Filters

There is no longer a static property for holding the global filers (GlobalFilters.Filters), instead, they can be added to the services collection, normally through the AddMvc overload that takes a lambda:

services.AddMvc(mvc =>

{

    mvc.Filters.Add(typeof(MyActionFilter));

});

Of course, it is still possible to scope filters at the class or method level, using either an attribute inheriting from a *FilterAttribute class (like ActionFilterAttribute) or using TypeFilterAttribute, for dependency injection.

View Components and Tag Helpers

These are new in Core 1. I wrote about View Components here and on Tag Helpers here, so I’m not delving into it again. Two very welcome additions indeed!

Bundling

In the old days, you would normally use the Microsoft ASP.NET Web Optimization package to bundle and minify your JavaScript and CSS files. Now, by default, Gulp is used for that purpose. You can also use BundleMinifier.Core from Mads Kristensen, this needs to be added as a tool and configured through a bundleconfig.json file. BundleMinifier is installed by default starting with Visual Studio 2015 Tooling Preview 1.

Maintaining State

In pre-Core days, one could store state in the Application, which would be available to all requests. Unfortunately, this led to several problems, and the application storage was dropped. Of course, it is still possible to use static members and classes.

Likewise, the Cache storage was also dropped, this time in favor of a more flexible and extensible mechanism. You’ll need the Microsoft.Extensions.Caching.Abstractions Nuget package for the base contracts plus a specific implementation (see Memory or Redis, for example):

public void ConfigureServices(IServiceCollection services)

{

    services.AddDistributedMemoryCache();

 

    //...

}

 

public class MyController : Controller

{

    public MyController(IDistributedCache cache)

    {

        //...

    }

}

Sessions are still around, but they need to be explicitly configured. You need to add a reference to the Microsoft.AspNetCore.Session package, and then register the services and middleware (a distributed memory cache is also required):

public void ConfigureServices(IServiceCollection services)

{

    services.AddDistributedMemoryCache();

    services.AddSession();

}

 

public void Configure(IApplicationBuilder app)

{

    app.UseSession();

    app.UseMvc();

}

 

After this, the ISession instance can be accessed through the HttpContext instance exposed, for example, by the Controller class.

There is no longer support for automatically storing the session in a SQL Server database or the ASP.NET State Service, but it is possible to use Redis, a very popular distributed cache technology.

Publishing

Publish profiles are still around, but now you have other options, such as deploy to Docker. There’s also the dotnet publish command, which places all deployable artifacts in a folder, ready to be copied to the server.

Conclusion

You can see that even though this is still MVC, a lot has changed. In my next post, I will talk a bit about some of the new interfaces that were introduced. In the meantime, hope this gets you up and running! Do let me know if I skipped something or you wish to know more about this. Your feedback is always greatly appreciated!

ASP.NET MVC Core: The Good Parts

MVC 6 should be out any day, so we need to be prepared.

The good thing is, it’s all very similar to MVC 5; the even better thing is, it got better! A couple of ways it is so cool, in my mind, are:

  • Most of the stuff is very similar to what we had: controllers, views, mostly work the same way;
  • MVC and Web API have been merged together, so it’s not really any different add an API controller that returns JSON or an MVC controller that returns an HTML view;
  • All of its code is available in GitHub, and you can even contribute to it;
  • It is now cross-platform, meaning, you will be able to deploy your web app to Linux (even as a Docker container) and Mac (if you use .NET Core);
  • It is very modular: you only add to your project the Nuget packages you really need;
  • It now uses service providers to resolve all of its features; you do not need to know the static location of properties, like, ControllerBuilder.Current, GlobalFilters.Filters, etc; the boilerplate configuration in the Startup class is pretty easy to follow and change;
  • The default template has Bower, NPM and Gulp support out of the box;
  • No need to explicitly add attribute routing, it is built-in by default;
  • We have a better separation of contents and code, in the form of the wwwroot folder to which servable contents are moved;
  • Logging is injected, as are most of the services we need, or we can easily add our own without the need to add any IoC library; even filters can come from IoC;
  • It is now possible to have our Razor pages inherit from a custom class, have custom functions defined in Razor (by the way, do not use it!) and inject components into it;
  • View components and tag helpers are a really cool addition;
  • The new OWIN-based pipeline that is now ASP.NET is much more extensible and easy to understand than System.Web-based ASP.NET used to be;
  • This one is a corollary from the latter: Web.config is gone; let’s face it, it was a big beast, so it’s better to just drop it.

On the other hand, we will need to learn a lot of new stuff, namely, a whole lot of new interfaces and base classes to use. Also, it may sometimes be a bit tricky to find out which Nuget package contains that specific API we’re after. And because there is no more System.Web, all of the infrastructure management is very different. Finally, not all the libraries we’re used to will be immediately available for .NET Core, but that’s really not a problem with ASP.NET Core itself.

All in all, I think it is a good thing! I’ll be talking more on ASP.NET Core, so stay tuned!

Implementing Missing Features in Entity Framework Core – Part 4: Conventions

Conventions

This will be the fourth in a series of posts about bringing the features that were present in Entity Framework pre-Core into EF Core. The others are:

  • Part 1: Introduction, Find, Getting an Entity’s Id Programmatically, Reload, Local, Evict
  • Part 2: Explicit Loading
  • Part 3: Validations

Conventions are a mechanism by which we do not have to configure specific aspects of our mappings over and over again. We just accept how they will be configured, of course, we can override them if we need, but in most cases, we’re safe.

In EF 6.x we had a number of built-in conventions (which we could remove) but we also had the ability to add our own. In Entity Framework Core 1, this capability hasn’t been implemented, or, rather, it is there, but hidden under the surface.

A lot has changed. As of Entity Framework Core, conventions are specific to the provider in use, which makes perfect sense. But then we have several kinds of conventions. Just to give you an idea, the ConventionSet class exposes 15 convention collections! This is the place where we can register our own conventions, but there are two problems:

  • The current ConventionSet instance is not publicly accessible, so we need to use reflection to get hold of it;
  • We don’t want to add a new “blank” instance of ConventionSet because this way we would lose all of the conventions that would have been injected by the provider.

So, the solution I came up with had to use reflection to get the current convention set and allow adding new conventions, which is not ideal. Let’s see the code.

We need an extension method to get hold of the ConventionSet from the ModelBuilder and allow adding a convention, in the form of a IModelConvention:

public static class ModelBuilderExtensions

{

    public static ModelBuilder AddConvention(this ModelBuilder modelBuilder, IModelConvention convention)

    {

        var imb = modelBuilder.GetInfrastructure();

        var cd = imb.Metadata.ConventionDispatcher;

        var cs = cd.GetType().GetField("_conventionSet", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(cd) as ConventionSet;

 

        cs.ModelBuiltConventions.Add(convention);

 

        return modelBuilder;

    }

 

    public static ModelBuilder AddConvention<TConvention>(this ModelBuilder modelBuilder) where TConvention : IModelConvention, new()

    {

        return modelBuilder.AddConvention(new TConvention());

    }

}

Feel free to cache the _conventionSet field somewhere, but that is not the point of this post.

You can see that we are adding the new convention to the ModelBuiltConventions collection, basically, because this is the only collection that Entity Framework Core will go through during the OnModelCreating method, all of the other collections will have been processed before it. We’re cool with that.

Let’s see two examples of sample conventions, first, one to set the maximum length of strings, where it hasn’t been explicitly set:

public sealed class DefaultStringLengthConvention : IModelConvention

{

    internal const int DefaultStringLength = 50;

    internal const string MaxLengthAnnotation = "MaxLength";

 

    private readonly int _defaultStringLength;

 

    public DefaultStringLengthConvention(int defaultStringLength = DefaultStringLength)

    {

        this._defaultStringLength = defaultStringLength;

    }

 

    public InternalModelBuilder Apply(InternalModelBuilder modelBuilder)

    {

        foreach (var entity in modelBuilder.Metadata.GetEntityTypes())

        {

            foreach (var property in entity.GetProperties())

            {

                if (property.ClrType == typeof(string))

                {

                    if (property.FindAnnotation(MaxLengthAnnotation) == null)

                    {

                        property.AddAnnotation(MaxLengthAnnotation, this._defaultStringLength);

                    }

                }

            }

        }

 

        return modelBuilder;

    }

}

Easy, easy, hey? We go through all of the mapped entities, then through all of their properties of type string, check if the maximum length annotation is present, and, if not, add a new one. Only one method, with access to all mapped entities.

Another example, turning off the table pluralization. As you know, as of EF RC2, table names of DbSet properties exposed in the DbContext are pluralized. We can get rid of this behavior if we explicitly set the name to something, in this case, it will be the entity type name:

public sealed class SingularizeTableNameConvention : IModelConvention

{

    public InternalModelBuilder Apply(InternalModelBuilder modelBuilder)

    {

        foreach (var entity in modelBuilder.Metadata.GetEntityTypes())

        {

            if (entity.FindAnnotation(RelationalAnnotationNames.TableName) == null)

            {

                entity.Relational().TableName = entity.Name.Split('.').Last();

            }

        }

 

        return modelBuilder;

    }

}

Now, some new extension methods come handy:

public static ModelBuilder UseDefaultStringLength(this ModelBuilder modelBuilder, int defaultStringLength = DefaultStringLengthConvention.DefaultStringLength)

{

    modelBuilder.AddConvention(new DefaultStringLengthConvention(defaultStringLength));

 

    return modelBuilder;

}

 

public static ModelBuilder UseSingularTableNames(this ModelBuilder modelBuilder)

{

    modelBuilder.AddConvention<SingularizeTableNameConvention>();

 

    return modelBuilder;

}

And that’s it! The way to apply these conventions (one or both) is during OnModelCreating:

protected override void OnModelCreating(ModelBuilder modelBuilder)

{

    modelBuilder

        .UseDefaultStringLength()

        .UseSingularTableNames();

 

    base.OnModelCreating(modelBuilder);

}

You can now reuse these conventions in all of your context classes very easily. Hope you enjoy it! Two final remarks about this solution:

  • The reflection bit is a problem, because things may change in the future. Hopefully Microsoft will give us a workaround;
  • There is no easy way to remove built-in (or provider-injected) conventions, because are applied before OnModelCreating, but I think this is not a big problem, since we can change them afterwards, as we’ve seen.

Stay tuned for more!

Entity Framework Pitfalls: Migrations and DbContext Construction

If you want to create or apply a migration over a DbContext-derived context and your context doesn’t have a public parameterless constructor, it will fail. This happens with both .NET Framework and .NET Core: the problem is that the migrations framework has no way of knowing how to create the context so as to get information from it, the migrations framework actually instantiates it!

There are two ways to go around it:

  • Create a public parameterless constructor on your context;
  • Create a class that implements IDbContextFactory<T>, where the generic parameter is your DbContext-derived class.

Having a parameterless constructor is not always ideal, because you may need to pass something in, like a connection string, but you can do it just for executing migrations and them remove it again. Just make sure that the connection string in use is the right one.

As for the IDbContextFactory<T> approach, it’s quite simple:

public class BlogContextFactory : IDbContextFactory<BlogContext>

{

    public BlogContext Create()

    {

        var connectionString = "get a connection string somehow";

        return new BlogContext(connectionString);

    }

}

Basically, you have to implement the Create method so as to return an instance of your context, doesn’t really matter how you instantiate it. The migrations API will find this class automatically.

If you don’t do any of this, you may get weird errors, like, “unable to find the DbContext”, which doesn’t really help much.

Another problem you may face is if you have multiple DbContexts, in that case, you have to tell migrations which one to use.

Implementing Missing Features in Entity Framework Core – Part 3

Back after a few weeks. For those who don’t know, this series of posts is dedicated to bringing some of the futures that existed in Entity Framework but were dropped in Core. You can find the first post here and the second here.

This time, an often forgotten feature that didn’t made it to Core: entity validation. Most of the posts that talk about what’s new usually forget about validation having been left out.

In a nutshell, Entity Framework used to validate entities according to the System.ComponentModel.DataAnnotations API:

It’s simple to get these back, though. All you need to do is override SaveChanges and plug in the validation code for all new and modified entries:

public class MyContext : DbContext

{

    public override int SaveChanges(bool acceptAllChangesOnSuccess)

    {

        var serviceProvider = this.GetService<IServiceProvider>();

        var items = new Dictionary<object, object>();

        

        foreach (var entry in this.ChangeTracker.Entries().Where(e => (e.State == EntityState.Added) || (e.State == EntityState.Modified))

        {

            var entity = entry.Entity;

            var context = new ValidationContext(entity, serviceProvider, items);

            var results = new List<ValidationResult>();

 

            if (Validator.TryValidateObject(entity, context, results, true) == false)

            {

                foreach (var result in results)

                {

                    if (result != ValidationResult.Success)

                    {

                        throw new ValidationException(result.ErrorMessage);

                    }

                }

            }

        }

 

        return base.SaveChanges(acceptAllChangesOnSuccess);

    }

}

The key here is the Validator class: it knows how to perform all these validations, including finding all validation attributes in the class and in each property. In case of an error, we just throw a ValidationException with the error message, and the saving is aborted.

ASP.NET Core Inversion of Control and Dependency Injection

Introduction

There are quite a few good posts out there on Inversion of Control (IoC) and Dependency Injection (DI) in the ASP.NET Core world, but I felt there was still something to be said, hence this post! Mind you, this is going to be a long one! I once wrote another post on the history of dependency resolution in .NET, you may want to have a look at it. Always keep in mind that this is based on the latest bits, and may still change when it gets to the final version.

Services Registration

At bootstrap, ASP.NET Core will either call the ConfigureServices method, or one with a name following the convention Configure<environment>Services, where <environment> comes from the Hosting:Environment environment variable, and you can also set it in Visual Studio:

image

It is commonly set to “Development”, “Production”, “Staging”, etc. Keep in mind that if the environment-specific method exists (e.g., ConfigureDevelopmentServices), then the generic one (ConfigureServices) is not called.

The Configure*Services method is passed an instance of IServiceCollection, which is where we get to store our service registrations, so that they can be used by ASP.NET Core further along the pipeline. A service registration needs three things:

  • A key type, normally an interface or an abstract base class;
  • A concrete implementation of the key type;
  • A lifetime.

The lifetime determines how many times the concrete implementation is going to be built. The ASP.NET Core service provider implementation knows about three different lifetimes:

  • Scoped: an instance is created the first time it is requested during the same HTTP request, and during that request, this same instance is always returned;
  • Singleton: an instance is created the first time it is requested, and this same instance is always returned in all subsequent calls;
  • Transient: a new instance is always created, whenever it is requested.

A registration is an instance of the ServiceDescriptor class that is added to the IServiceCollection instance:

services.Add(new ServiceDescriptor(typeof(IMyService), typeof(MyService), ServiceLifetime.Singleton));

There are several extension methods that make this registration even easier.

What if you want to have custom processing when a service is returned? Simple:

services.AddTransient<IMyService>(sp =>

{

    var something = sp.GetService(typeof(ISomething)) as ISomething;

    var other = new OtherService();

    //do something with it

    return new MyService(other);

});

Keep in mind that the concrete service must either implement or inherit from the key service. Also, for the Scoped lifetime, if the concrete class implements IDisposable, the service provider will honor it and call Dispose at the end of the HTTP request.

After Configure*Services, ASP.NET Core calls Configure, also in the Startup class. This is where the core initialization occurs, like, adding all middleware, such as the MVC one, that makes the application works the way we expect it. The Configure method can either have no parameters or it can receive one or more parameters with types that match the registered services. For example, we will always have IApplicationBuilder, IHostingEnvironment, ILoggerFactory, so we can add them as parameters together with our own:

public void Configure(

    IApplicationBuilder app,

    IHostingEnvironment env,

    ILoggerFactory loggerFactory,

    IMyService service)

{

    //do something with the services

}

It gives us a good chance to initialize them before the actual fun begins. If we want, we can also pass it just an instance of the dependency resolution service, represented by the IServiceProvider interface, which has been around since the early days of .NET. The ASP.NET Core service provider implements this interface, so having it here just means: “get me the service provider implementation so that I can retrieve services from it”:

public void Configure(IServiceProvider serviceProvider)

{

    var env = serviceProvider.GetService(typeof(IHostingEnvironment)) as IHostingEnvironment;

    var service = serviceProvider.GetService(typeof(IMyService)) as IMyService;

}

In the latest version of ASP.NET Core, there is no globally accessible reference to the built-in service provider, something known as the service locator, of bad reputation. If, for any reason you feel you need it, here is the place to store it. By the way, the Microsoft.Extensions.DependencyInjection package has some good strongly typed extension methods for IServiceProvider, make sure you include it.

Services

Each concrete service class itself can be dependency-injected: by default, it should be a concrete class and have a public parameter-less constructor; if, however, we want to inject dependencies into it, which also need to be registered in the service provider, we can have a constructor that takes these dependencies:

public class MyService : IMyService

{

    public MyService(IServiceProvider serviceProvider)

    {

        //get something from the service provider

    }

}

Notice the usage of IServiceProvider again. Another option is to have the constructor contain more concrete dependencies:

public class MyService : IMyService

{

    public MyService(ILoggerFactory loggerFactory)

    {

        //do something with the logger factory

    }

}

You can pass any number of parameters, of any type that is registered in the service provider, normally in one of the Configure*Services methods. If the specified service type is not registered, you get an exception at runtime.

Controllers

An MVC controller can have dependencies injected through its constructor, like I’ve shown for services:

public class HomeController : Controller

{

    public HomeController(IMyService service)

    {

        //do something with the service

    }

}

The same pattern applies: we can either declare a parameter as IServiceProvider or as a more specific type. It doesn’t matter if our controller inherits from Controller or is a POCO controller.

There was another dependency injection possibility with MVC controllers, which consisted in decorating public properties with a [FromServices] attribute: if a registration exists that matched the property’s type, it would be injected into the property just after the controller is constructed:

public class HomeController

{

    [FromServices]

    public IService Service { get; set; }

}

This is no longer possible, and the functionality was removed in DNX RC2, although it will still work in RC1. Forget about it.

By default, controller classes themselves do not come from the dependency resolution mechanism. You can achieve that, if, in Configure*Services, you call AddControllersAsServices, passing it either a Type or an Assembly collection:

services

    .AddMvc()

    .AddControllersAsServices(new[] { typeof(HomeController).GetTypeInfo().Assembly });

This allows you to do this:

services.AddSingleton<HomeController, SingletonHomeController>();

Each time MVC tries to build an HomeController, it will instead get the same SingletonHomeController. Note that I am not saying that you should do this, but I think you get the idea!

Filters

Filters in MVC allow you to intercept action method calls, results and exceptions, and do stuff before, after of instead of the real actions. You have global filters and attribute filters: global filters apply always, and attribute filters only apply in the scope where they are declared – a controller’s class or an action method. Filters themselves can have dependencies injected into them.

In order to declare global filters, you use one of the overloads of the AddMvc method, normally in the Configure*Services method, and registering the filter as a service:

services.AddMvc(mvc => mvc.Filters.AddService(typeof(GlobalFilter)));

MVC will try to resolve the filter type, if necessary, injecting it any dependencies, in the usual way:

public class GlobalFilter : IActionFilter

{

    public GlobalFilter(IMyService service)

    {

        //do something with the service

    }

 

    public void OnActionExecuted(ActionExecutedContext context)

    {            

    }

 

    public void OnActionExecuting(ActionExecutingContext context)

    {

    }

}

The other option for filters is attributes, but attributes require a public parameter-less constructor. The MVC team came up with an alternative for that, in the form of the ServiceFilterAttribute and TypeFilterAttribute attributes. Both receive a Type and the difference is that the first will try to resolve that type from the services registration and the last one will just instantiate it. Let’s see an example:

[ServiceFilter(typeof(GlobalFilter))]

public class HomeController : Controller

{

    [TypeFilter(typeof(SomeFilter))]

    public IActionResult Index()

    {

        //...

    }

}

So, GlobalFilter is retrieved from the services registration, and, if it is a filter, it will behave accordingly to the context where it is located, in this case, it is the whole controller. SomeFilter, on the other hand, is just instantiated and used, no need to have it registered. Don’t forget that types passed to ServiceFilterAttribute and TypeFilterAttribute have to implement one of the filter interfaces in namespace Microsoft.AspNet.Mvc.Filters otherwise an exception is thrown.

Models

Model classes are declared as parameters to action methods in an MVC controller. There’s a binding mechanism that fills their properties automatically, but we can also use dependency injection here.

First, the whole model can come from dependency injection:

public IActionResult Index([FromServices] IMyService service)

{

    //...

}

Or, at least, some properties of the model:

public IActionResult Update(Model model)

{

    //...

}

 

public class Model

{

    [FromServices]

    public IMyService Service { get; set; }

 

    //...

}

Views

MVC views can also take injected services, through the @inject directive:

@inject IMyService service;

 

<p>@service.Serve()</p>

View Components

View components, introduced in ASP.NET MVC Core, can also be injected in pretty much the same way as controllers:

public class MyServiceViewComponent : ViewComponent

{

    public MyServiceViewComponent(IMyService service)

    {

        //do something with the service

    }

    

    public string Invoke()

    {

        //...

    }

}

Tag Helpers

Tag helpers, like view components and controllers, also support constructor injection:

[HtmlTargetElement("service")]

public class ServiceTagHelper : TagHelper

{

    public ServiceTagHelper(IMyService service)

    {

        //do something with the service

    }

 

    public override void Process(TagHelperContext context, TagHelperOutput output)

    {

        //...

    }

}

Middleware

OWIN-style middleware are likewise injectable through the constructor:

public class ServiceMiddleware

{

    private readonly RequestDelegate _next;

    

    public ServiceMiddleware(RequestDelegate next, IMyService service)

    {

        this._next = next;

        //do something with the service

    }

    

    public Task Invoke(HttpContext httpContext)

    {

        //...

    }

}

Using a Custom IoC/DI Container

Now, you may not want to use the built-in service provider and use your own (Unity, Autofac, Ninject, TinyIoC, etc). That is certainly possible!

You need to change the signature of the Configure*Services method so as to return an IServiceProvider:

public IServiceProvider ConfigureServices(IServiceCollection services)

{

    services.AddMvc();

 

    services.AddTransient<IMyService, MyService>();

 

    return new MyIoCContainer(services.BuildServiceProvider());

}

The key here is to create an instance of the service provider we want to use, maybe leveraging on the one produced from the service collection (BuildServiceProvider method), and return it here. Of course, if it has more features and lifetimes than the default one, you are free to use them all. The only contract it has to comply to is that of IServiceProvider.

Dependency Resolution

While running your MVC application, you can explicitly ask for services registered in the global (the default or your own) service provider. The HttpContext class exposes a RequestServices property; here you will find the custom service provider that you returned in Configure*Services, or ASP.NET Core’s built-in one. Whenever you have a reference to the current HttpContext (controllers, view components, tag helpers, views, middleware, filters), you get it as well. The “old” ApplicationServices was removed in recent commits, so it won’t make it to the final version of ASP.NET Core and you shouldn’t be using it.

Conclusion

The dependency injection mechanism was substantially changed in ASP.NET Core. The only identical feature seems to be constructor injection, and it is understandable, since it’s what most people should be using anyway. Now every moving part of ASP.NET Core is injectable through the same mechanism, which I think is a good thing. The problems so far have been the relative instability in the ASP.NET Core, things have been changing a lot, and there is still no light at the end of the tunnel.