C# default constructor access modifier

Suggested Videos:
Part 12 - Difference between int and Int32 in c#
Part 13 - Reverse each word in a string using c#
Part 14 - C# abstract class virtual method

One of our YouTube channel subscribers faced this c# question in an interview for an entry level c# developer role. So here is the question.


What is the Access Modifier of the default parameter-less constructor in C#
The answer is Public


Let's prove this. Consider the following Customer class

class Customer
{
}

The Customer class does not have an explicit constructor defined. In C#, if we do not provide an explicit constructor, a default parameter-less constructor is automatically provided. The access modifier for that constructor is Public.

We can prove this using the following reflection code.

using System;
using System.Reflection;

namespace Demo
{
    class Program
    {
        static void Main(string[] args)
        {
            Type type = typeof(Customer);
            // Type.EmptyTypes represents an Empty Type[] array
            // We use an Empty Type[] array to get the Constructor that 
            // takes no parameters
            ConstructorInfo constructorInfo = type.GetConstructor(Type.EmptyTypes);
            Console.WriteLine("Is Constructor : " + constructorInfo.IsConstructor);
            Console.WriteLine("Is Public : " + constructorInfo.IsPublic);
        }
    }

    class Customer
    {
    }
}

Output:
Is Constructor : True
Is Public : True

The following code checks if the constructor is private or protected

using System;
using System.Reflection;

namespace Demo
{
    class Program
    {
        static void Main(string[] args)
        {
            Type type = typeof(Customer);
            ConstructorInfo constructorInfo = type.GetConstructor(
                BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic,
                null, Type.EmptyTypes, null);
            Console.WriteLine("Is Constructor : " + constructorInfo.IsConstructor);
            Console.WriteLine("Is Protected : " + constructorInfo.IsFamily);
        }
    }

    class Customer
    {
        protected Customer()
        { }
    }
}

C# default constructor access modifier - Slides







Controller in ASP.NET Core MVC

Suggested Videos
Part 17 - ASP.NET Core AddMvc vs AddMvcCore | Text | Slides
Part 18 - Model in ASP.NET Core MVC | Text | Slides
Part 19 - ASP.NET Core dependency injection tutorial | Text | Slides

In this video we will discuss, what is Controller and it's role in ASP.NET Core MVC.


Controller in MVC

Controller in ASP.NET Core MVC
  • Controller in MVC is a class and it inherits from Microsoft.AspNetCore.Mvc.Controller
  • The controller class name is suffixed with word "Controller". For example HomeController, EmployeeController.
  • When a request from the browser arrives at our application, it is the controller in the MVC design pattern, that handles the incoming http request and responds to the user action. 
  • Controller class contains a set of public methods. These public methods in the Controller class are called action methods. It is these controller action methods that handle and process the incoming http request.
  • Let's say the user has typed the following URL in the browser address bar and hit the ENTER keyhttp://localhost:12345/home/details
  • The URL "/home/details" is mapped to the "Details" public action method in the HomeController. This mapping is done by the routing rules defined in our application. 
  • We will discuss Routing in ASP.NET Core MVC in detail in our upcoming videos.
  • The request arrives at a controller action method. As part of processing that request, the controller creates the Model
  • To retrieve model data, the controller depends on a service. 
  • For example, in our case to retrieve Employee data, HomeController depends on IEmployeeReporsitory service. 
  • IEmployeeReporsitory service is injected into the HomeController using the constructor. This is called Dependency Injection. 
  • We discussed Dependency Injection in our previous video of this ASP.NET Core tutorial.
  • Notice, we are assigning the injected dependency to a read-only field. This is a good practice as it prevents accidentally assigning another value to it inside a method.
  • Once the controller has the required model data, it can simply return that model data if we are building a RESTful service or an API.
Controller returns JSON data

The following example returns JSON data. Notice, the return type of the Details() method is set to JsonResult as we are explicitly returning JSON data. In this case, Details() method always returns JSON data. It does not respect content negotiation and ignores the Accept Header.

public class HomeController : Controller
{
    private readonly IEmployeeRepository _employeeRepository;

    public HomeController(IEmployeeRepository employeeRepository)
    {
        _employeeRepository = employeeRepository;
    }

    public JsonResult Details()
    {
        Employee model = _employeeRepository.GetEmployee(1);
        return Json(model);
    }
}

Controller returns ObjectResult

The following example respects content negotiation. It looks at the Request Accept Header and if it is set to application/xml, then XML data is returned. If the Accept header is set to application/json, then JSON data is returned.

public class HomeController : Controller
{
    private IEmployeeRepository _employeeRepository;

    public HomeController(IEmployeeRepository employeeRepository)
    {
        _employeeRepository = employeeRepository;
    }

    public ObjectResult Details()
    {
        Employee model = _employeeRepository.GetEmployee(1);
        return new ObjectResult(model);
    }
}

Please note : To be able to return data in XML format, we have to add Xml Serializer Formatter by calling AddXmlSerializerFormatters() method in ConfigureServices() method in Startup.cs file.

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc().AddXmlSerializerFormatters();
}

Controller returns View

The following example returns a View. Notice we have set ViewResult as the return type for the Details method as we are returning a view. 

public class HomeController : Controller
{
    private IEmployeeRepository _employeeRepository;

    public HomeController(IEmployeeRepository employeeRepository)
    {
        _employeeRepository = employeeRepository;
    }

    public ViewResult Details()
    {
        Employee model = _employeeRepository.GetEmployee(1);
        return View(model);
    }
}

At this point if we run the application and navigate to http://localhost:49119/home/details, we get the following error. This  is because we do not have the required View file created yet. We will discuss Views in MVC in our next video.

InvalidOperationException: The view 'Details' was not found. The following locations were searched: /Views/Home/Details.cshtml /Views/Shared/Details.cshtml /Pages/Shared/Details.cshtml

Summary
  • When a request from the browser arrives at our application, it is the controller in the MVC design pattern, that handles the incoming http request and responds to the user action. 
  • The controller builds the model AND
  • Returns the Model data to the caller if we are building an API  OR
  • Select a View and pass the model data to the view
  • The View then generates the required HTML to present the data
Next video: Views in MVC

asp.net core tutorial for beginners

Controller in ASP.NET Core MVC - Slides





ASP.NET Core dependency injection tutorial

Suggested Videos
Part 16 - Setup mvc in asp.net core | Text | Slides
Part 17 - ASP.NET Core AddMvc vs AddMvcCore | Text | Slides
Part 18 - Model in ASP.NET Core MVC | Text | Slides

In this video we will discuss dependency injection in detail with an example.


HomeController

public class HomeController : Controller
{
    private IEmployeeRepository _employeeRepository;

    // Inject IEmployeeRepository using Constructor Injection
    public HomeController(IEmployeeRepository employeeRepository)
    {
        _employeeRepository = employeeRepository;
    }

    // Retrieve employee name and return
    public string Index()
    {
        return _employeeRepository.GetEmployee(1).Name;
    }
}


Please note :
  • HomeController is dependant on IEmployeeRepository for retrieving Employee data.
  • Instead of the HomeController creating a new instance of an implement ion of IEmployeeRepository, we are injecting IEmployeeRepository instance into the HomeController using the constructor. 
  • This is called constructor injection, as we are using the constructor to inject the dependency.
  • Notice, we are assigning the injected dependency to a read-only field. This is a good practice as it prevents accidentally assigning another value to it inside a method.
  • At this point, if we run the project we get the following error
    InvalidOperationException: Unable to resolve service for type 'EmployeeManagement.Models.IEmployeeRepository' while attempting to activate 'EmployeeManagement.Controllers.HomeController'.
  • This is because the ASP .NET dependency injection container does not know which object instance to provide if someone requests an object that implements IEmployeeRepository
  • IEmployeeRepository may have several implementations. At the moment in our project we only have one implementation and that is MockEmployeeRepository
  • As the name implies, MockEmployeeRepository works with the in-memory employee mock data.
  • In our upcoming videos, we will discuss providing another implementation for IEmployeeRepository which retrieves employee data from SQL Server database.
  • For now, let's work with MockEmployeeRepository.
  • To fix the InvalidOperationException error, we need to register MockEmployeeRepository class with the dependency injection container in ASP.NET core.
  • We do this in ConfigureServices() method in Startup class
Registering Services with the ASP.NET Core Dependency Injection Container : 

ASP.NET core provides the following 3 methods to register services with the dependency injection container. The method that we use determines the lifetime of the registered service.

AddSingleton() - As the name implies, AddSingleton() method creates a Singleton service. A Singleton service is created when it is first requested. This same instance is then used by all the subsequent requests. So in general, a Singleton service is created only one time per application and that single instance is used throughout the application life time.

AddTransient() - This method creates a Transient service. A new instance of a Transient service is created each time it is requested. 

AddScoped() - This method creates a Scoped service. A new instance of a Scoped service is created once per request within the scope. For example, in a web application it creates 1 instance per each http request but uses the same instance in the other calls within that same web request.

Please do not worry, if this is a bit confusing at the moment. We will be revisiting these 3 methods several times in our upcoming videos in this series.

For now, to fix the InvalidOperationException error, let's register MockEmployeeRepository class with the ASP.NET Core Dependency Injection container using AddSingleton() method as shown below. So, with this code in-place, if someone asks for IEmployeeRepository, an instance of MockEmployeeRepository will be provided.

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc();
    services.AddSingleton<IEmployeeRepository, MockEmployeeRepository>();
}

At this point, you might be thinking, why do we have to do all this. Why can't we simply create an instance of MockEmployeeRepository class in the HomeController using the new keyword as shown below.

public class HomeController : Controller
{
    private readonly IEmployeeRepository _employeeRepository;

    // Inject IEmployeeRepository using Constructor Injection
    public HomeController(IEmployeeRepository employeeRepository)
    {
        _employeeRepository = new MockEmployeeRepository();
    }

    // Retrieve employee name and return
    public string Index()
    {
        return _employeeRepository.GetEmployee(1).Name;
    }
}

Well, this makes HomeController tightly coupled to MockEmployeeRepository. Later if we provide a new implementation for IEmployeeRepository and if we want to use that new implementation instead of MockEmployeeRepository, we have to change the code in HomeController. You might be thinking, this is just one line of code change, so it is not that difficult to do.

Well, what if we have used this MockEmployeeRepository in 50 other controllers in our application?
The code in all the 50 controllers has to change. This is not only tedious but also error prone.

So in-short, using the new keyword to create instances of dependencies creates tight coupling and as a result your application will be difficult to change. With dependency injection we will not have this tight coupling. 

With dependency injection, even, if we have used MockEmployeeRepository in 50 other controllers in our application, if we want to swap it out with a different implementation, we just need to change the following one line of code in Startup.cs file. Notice, we are now using DatabaseEmployeeRepository instead of MockEmployeeRepository

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc();
    services.AddSingleton<IEmployeeRepository, DatabaseEmployeeRepository>();
}

Unit testing also becomes much easier, as we can easily swap out dependencies with dependency injection.

Don't worry, if this is slightly confusing. We will provide a different implementation for IEmployeeRepository in our upcoming videos. This new implementation will retrieve data from a SQL Server database. We will then replace the MockEmployeeRepository implementation with the DatabaseEmployeeRepository implementation. At that point, you will understand the power and flexibility dependency injection provides.

asp.net core tutorial for beginners

ASP.NET Core dependency injection tutorial - Slides





Model in ASP.NET Core MVC

Suggested Videos
Part 15 - ASP.NET Core MVC tutorial | Text | Slides
Part 16 - Setup mvc in asp.net core | Text | Slides
Part 17 - ASP.NET Core AddMvc vs AddMvcCore | Text | Slides

In this video we will discuss Model in ASP.NET Core MVC with an example. 


We want to ultimately, retrieve a specific employee details from the Employees database table and display on the web page as shown below.

asp.net core model in mvc


Model in MVC contains a set of classes that represent data and the logic to manage that data. So, to represent the employee data that we want to display, we use the following Employee class.

public class Employee
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Email { get; set; }
    public string Department { get; set; }
}

Model classes in ASP.NET Core does not have to be in the Models folder, but keeping them in a folder named Models is a good practice as it is easier to find them later.

In addition to the Employee class that represent the data, model also contains the class that manages the model data. To manage the data i.e to retrieve and save employee data we are going to use the following IEmployeeRepository service. At the moment, we only have one method GeEmployee() that retrieves employee by ID. As we progress through the course we will add methods to Create, Update and Delete as well.

public interface IEmployeeRepository
{
    Employee GetEmployee(int Id);
}

The following MockEmployeeRepository class provides the implementation for IEmployeeRepository interface. At the moment, we are hard coding the Employee data in the MockEmployeeRepository class. In our upcoming videos, we will provide another implementation for IEmployeeRepository interface, and that implementation will retrieve data from a SQL Server database.

public class MockEmployeeRepository : IEmployeeRepository
{
    private List<Employee> _employeeList;

    public MockEmployeeRepository()
    {
        _employeeList = new List<Employee>()
        {
            new Employee() { Id = 1, Name = "Mary", Department = "HR", Email = "mary@pragimtech.com" },
            new Employee() { Id = 2, Name = "John", Department = "IT", Email = "john@pragimtech.com" },
            new Employee() { Id = 3, Name = "Sam", Department = "IT", Email = "sam@pragimtech.com" },
        };
    }

    public Employee GetEmployee(int Id)
    {
        return this._employeeList.FirstOrDefault(e => e.Id == Id);
    }
}

Throughout our application we will be programming against the interface IEmployeeRepository and not the concrete implementation MockEmployeeRepository. This interface abstraction allows us to use dependency injection which in turn makes our application flexible and easily unit testable. We will discuss Dependency Injection in detail in our next video.

asp.net core tutorial for beginners

Model in ASP.NET Core MVC - Slides







ASP.NET Core AddMvc vs AddMvcCore

Suggested Videos
Part 14 - ASP.NET Core environment variables | Text | Slides
Part 15 - ASP.NET Core MVC tutorial | Text | Slides
Part 16 - Setup mvc in asp.net core | Text | Slides

In this video we will discuss the difference between AddMvc() and AddMvcCore() methods. 


To setup MVC in an ASP.NET Core application we call AddMvc() method of the IServiceCollection interface in ConfigureServices() method of the Startup class.

services.AddMvc();


In addition to AddMvc() method we also have AddMvcCore() method on the IServiceCollection interface. So, the obvious question that comes to our mind is, what's the difference between these 2 methods. 

AddMvc() v/s AddMvcCore()

Before we discuss the difference between AddMvc() and AddMvcCore() methods, let's modify the following HomeController to return JSON formatted data, instead of a simple string. 

At the moment, there is no base class specified for the the HomeController class. It works for us now because we are returning a simple string from the Index() action method.

public class HomeController
{
    public string Index()
    {
            return "Hello from MVC";
    }
}

However, if we want to return an HTML View or JSON data from the Index() action method, our HomeController class has to derive from the Controller class provided by the framework. The Controller base class provides support to return different results like JsonResult, ViewResult, PartialViewResult etc. Modify the HomeController class to derive from the Controller class and return JsonResult from the Index() action method as shown below.

public class HomeController : Controller
{
    public JsonResult Index()
    {
        return Json(new { id=1, name="pragim" });
    }
}

Please note : Controller class is present in Microsoft.AspNetCore.Mvc namespace.

At this point, run the application and we should see JSON data in the browser as expected.

Now, in the ConfigureServices() method call AddMvcCore() method instead of AddMvc() and run the application.

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvcCore();
}

We get the following error
No service for type 'Microsoft.AspNetCore.Mvc.Formatters.Json.Internal.JsonResultExecutor' has been registered.

To be able to return JSON data, JsonFormatterServices need to be registered with the dependency injection container. AddMvc() method does this but not the AddMvcCore() method. You can confirm this by looking at the source code on ASP.NET Core MVC Github page. 

As the name implies, AddMvcCore() method only adds the core MVC services. On the other hand, AddMvc() method adds all the required MVC services. AddMvc() method calls AddMvcCore() method internally, to add all the core MVC services. So if we are calling AddMvc() method there is no need to explicitly call AddMvcCore() method again.

I hope this clarifies the difference between AddMvc() and AddMvcCore() methods.

asp.net core tutorial for beginners

ASP.NET Core AddMvc vs AddMvcCore - Slides





Setup mvc in asp.net core

Suggested Videos
Part 13 - ASP.NET Core developer exception page | Text | Slides
Part 14 - ASP.NET Core environment variables | Text | Slides
Part 15 - ASP.NET Core MVC tutorial | Text | Slides

In this video we will discuss, setting up MVC in ASP.NET Core application.


The ASP.NET Core Project we have been working with so far in this video series is generated using the "Empty" project template. At the moment this project does not have MVC setup.


Two steps to setup MVC in ASP.NET Core Application

Step 1 : In ConfigureServices() method of the Startup class in Startup.cs file, include the following line. This line of code adds the required MVC services to the dependency injection container in asp.net core.

services.AddMvc();

Step 2 : In the Configure() method, add UseMvcWithDefaultRoute() midddleware to our application's request processing pipeline. Modify the code as shown below.

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    app.UseStaticFiles();

    app.UseMvcWithDefaultRoute();

    app.Run(async (context) =>
    {
        await context.Response.WriteAsync("Hello World!");
    });
}

Notice, we placed UseStaticFiles() middleware before UseMvcWithDefaultRoute() middleware. This order is important, because if the request is for a static file like an image, css or JavaScript file, then UseStaticFiles() middleware will handle the request and short-circuit the rest of the pipeline. 

So if the request is for a static file, UseMvcWithDefaultRoute() middleware is not executed, there by avoiding the unnecessary processing. 

On the other hand, if the request is an MVC request, UseStaticFiles() middleware will pass that request to UseMvcWithDefaultRoute() middleware which will handle the request and produces the response.

Notice, in addition to UseMvcWithDefaultRoute() middleware, we also have UseMvc() middleware. For now, let's use, UseMvcWithDefaultRoute() middleware. In our upcoming videos, when we discuss routing, we will discuss the difference between these 2 middlewares.

At this point, if we run the application and navigate to the root URL -http://localhost:49119, we see "Hello World!" message displayed in the browser.
  • With UseMvcWithDefaultRoute() middleware configured in the pipeline, when we issue a request to the root URL - http://localhost:49119
  • As the request is not for a static file, UseStaticFiles() middleware will pass the request to UseMvcWithDefaultRoute() middleware
  • Since we have not specified the controller and action method segments in the URL, UseMvcWithDefaultRoute() middleware looks for Index() action method in the HomeController.
  • Since, at the moment, we do not have a HomeController in our application, UseMvcWithDefaultRoute() middleware passes the request to the middleware registered using the Run() method and hence we see the "Hello World!" message produced by this middleware.
Now let's see, what happens if we remove the Run() middleware. At this point the code in your Configure() method must be as shown below.

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    app.UseStaticFiles();

    app.UseMvcWithDefaultRoute();
}

With the above code in place, if we again issue a request to the root URL - http://localhost:49119, we now see the 404 error. This is because UseMvcWithDefaultRoute() middleware did not find the HomeController with the Index() action and there is no other middleware in the pipeline, so we see 404 error.

Add HomeController

Add Controllers folder, in the root project folder. In the "Controllers" add a new Controller. Copy and paste the following code.

public class HomeController
{
    public string Index()
    {
        return "Hello from MVC";
    }
}

Build the solution and issue a request to the application root URL - http://localhost:49119. You will now see the string - "Hello from MVC" displayed in the browser.

asp.net core tutorial for beginners