MVC 5 Dependency Injection

This is the seventh and last part of building line of business application using MVC 5, the remaining parts will be recorded as videos which will be more effective, you can read the previous parts through the following links

  1. Building a LOB application with MVC 5 – Part 0
  2. Building a LOB application with MVC 5 – Part 1
  3. Building a LOB application with MVC 5 – Part 2 – Models and Generic Repository
  4. Building a LOB application with MVC 5 – Part 3 – EntityFramework
  5. Building a LOB application with MVC 5 – Part 4 – Controllers, Routes and Areas
  6. Building a LOB application with MVC 5 – Part 5 – Views

In the previous part, we talked about Views, Layouts, View Engine and how to pass data from controllers to views and vice versa.

In this part we will talk about Dependency Injection (DI) and Inversion of Control (IoC).

What is DI?

You can find a lot of posts and tutorials about the definition of DI and IoC, so we are not going to detail it here, to summarize, as per our multi-tier architecture, our controllers will need a domain service which will need a repository and finally the repository will need a data context, if we let each object creates its dependencies, we will end up with a big mess, imagine if you tried to create a unit test to test the controller action logic, it will cause lead to the creation of the full chain starting from the controller down to the data context , although we only needed to test the controller logic.

To overcome this issue, all the dependencies must be injected into each depending object either through a constructor parameter or a public property, since the controller is the first object in our chain, we will start with it, but before we proceed, lets first examine how DI works in MVC.

DI in MVC 5

In the previous posts, we created a controller name ServiceTypesController under the Admin area, when we request the path /Admin/ServiceTypes, you will find an empty page as we don’t have any data created yet, but how did MVC created an object of ServiceTypesController?

MVC 5 depends on a ControllerFactory to create new controllers, simply, it instantiate a new controller object and in order for this to work, the controller must have a parameterless constructor because this is the way the default controller factory works.

Enable DI in MVC

Now, we need to inject a domain service into the ServiceTypesController controller, we will add the following code and try to run the application.

   public class ServiceTypesController : Controller
    {
        IService<ServiceType, int> _serviceTypeService;

        public ServiceTypesController(IService<ServiceType, int> serviceTypeService)
        {
            this._serviceTypeService = serviceTypeService;
        }

        // GET: Admin/ServiceTypes
        public ActionResult Index()
        {
            return View(_serviceTypeService.GetAll());
        }
    }

As you can see, our constructor now has a new parameter of type IService<ServiceType, int>, this is the generic domain service that we created and it is enough for all CRUD operations for any of our domain model classes, now try to build and run the application and you will get the following error.

Parameterless Contructor.png

Of course you can remove the parameter from the constructor but then you will have to instantiate the object itself, this means the controller class will have to know which concrete type it should create which is not its responsibility.

Custom Controller Factory

To overcome this issue, we will have to create a custom controller factory that knows how to instantiate an object that implement the IService<ServiceType,int>

To do that, create a folder named Factories under the web project and inside this folder create a class named DIControllerFactory, the code should look like the following

public class DIControllerFactory : DefaultControllerFactory
    {
        public override IController CreateController(RequestContext requestContext, string controllerName)
        {
            if (controllerName.ToLower() == "servicetypes")
                return new ServiceTypesController(new BaseService<ServiceType, int>(new EFRepository<ServiceType, int>(new AppointmentManagerContext())));

            return base.CreateController(requestContext, controllerName);
        }
    }

As you can see, the method CreateController is responsible for creating the controller class and passing all the needed dependencies that the class needs, this will be easy if we have a controller or two, but when the number of controllers grow and the tree of dependencies grows, this will be a nightmare, have a look at the return statement in the above code, we instantiated 4 classes just to create the controller, this is where we need something else to manage that for us, something called the IoC Container.

There are a lot of IoC cotnainer available like, NInject, Microsoft Unity, StructureMap and many others, you can use any framework you like, in my case I will go with StructureMap

So, run the following NuGet Command to install StructureMap package, make sure it is installed in the MVC web project

Install-Package StructureMap

Now, it is time to setup the IoC container and let it know about our interfaces and its implementation, this will help when we ask it for an instance of the controller, then it will be able to resolve all the dependencies for it.

Setup StructureMap

Under App_Start, create a file called StructureMapConfig and add the following code

 public class StructureMapConfig
    {
        public static Container Container;

       public static IContainer Config()
        {
            Container = new Container();

            Container.Configure(c =>
            {
                c.Scan(s =>
                {
                    s.TheCallingAssembly();
                    s.WithDefaultConventions();
                });

                c.For(typeof(IService<,>)).Use(typeof(BaseService<,>));
                c.For(typeof(IRepository<,>)).Use(typeof(EFRepository<,>));
                c.For<ServiceTypesController>();
                c.For<DbContext>().Use<AppointmentManagerContext>();
            });

            return Container;
        }
    }

In the Config method, we created a container that will hold the information about the different interfaces and its implementation, notice that we registered all teh types for the IService and IRepository with only one call, this is why we use typeof(IService<,>), this will enable StructureMap to return any instance requested with the IService, for ex: IService<Appointment,int>, so you don’t have to register all the different combinations.

Call the Config method in the method Application_Start in the file Global.asax.cs

Now, back to the DIControllerFactory class, replace the code with the one below.

public class DIControllerFactory : DefaultControllerFactory
    {
        public override IController CreateController(RequestContext requestContext, string controllerName)
        {
            if (controllerName.ToLower() == "servicetypes")
            {
                return StructureMapConfig.Container.GetInstance<ServiceTypesController>();
            }

            return base.CreateController(requestContext, controllerName);
        }
    }

The difference is huge, only one line to build the object instead of creating 4 objects, but still we have to know the controller name and figure out the type, of course we can append the namespace to the controller name and build the controller type name but this won’t be neat.

MVC Dependency Rresolver

MVC Comes with a dependency resolver that can be replaced by calling the following line at the application start.

 DependencyResolver.SetResolver(new CustomDependencyResolver());

MVC asks the default depdnency resolver to create a new object/service that it may need, if we managed to inject our own depdenecy resolver, then all the controllers will be created automatically without the need for a controller factory, to do that, create a class called StructureMapDependencyResolver under the Factories folder, add the following code to it.

 public class StructureMapDependencyResolver : IDependencyResolver
    {
        private static IContainer _container;

        public StructureMapDependencyResolver(IContainer container)
        {
            _container = container;
        }

        public object GetService(Type serviceType)
        {
            if (serviceType == null)
                return null;

            try
            {
                return serviceType.IsAbstract || serviceType.IsInterface
                         ? _container.TryGetInstance(serviceType)
                         : _container.GetInstance(serviceType);
            }
            catch
            {
                return null;
            }
        }

        public IEnumerable<object> GetServices(Type serviceType)
        {
            return _container.GetAllInstances(serviceType).Cast<object>();
        }
    }

The class implements two methods, the GetService and GetServices,these methods are use to return instances for services that MVC uses, such as IControllerFactory, IControllerActivator, so this class is the top level for all teh DI work in MVC, the controller Factory class was just a small part of it.

Now update the code in the Application_Start method to register the new dependency resolver as below

 public class MvcApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            StructureMapConfig.Config();

            //ControllerBuilder.Current.SetControllerFactory(typeof(DIControllerFactory));
            DependencyResolver.SetResolver(new StructureMapDependencyResolver(StructureMapConfig.Container));

            AreaRegistration.RegisterAllAreas();
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
        }
    }

Notice the first line of the Configure block, it scans the current assembly to find any classes and interfaces and it does what with the default conventions as instructed by teh second line, this will make StructureMap to resolve automatically any reference to an interface that has a name like IService with a class that implements it with a name like Service

If you run the application now, it will work fine and all dependencies will be resolved automatically.

To conclude, always develop against an interface and leave the resolving of the actual implementation to an IoC container which as you can see, it is very easy to setup with MVC 5.

I hope this post was useful, if you have any questions, please leave a comment and you can get the code from the GitHub repository https://github.com/haitham-shaddad/AppointmentManager

Advertisements

Using GenFu to fill your database with dummy data

When you deliver a training or present a session or even start a new project, you want some test data pre-filled in your application instead of having to start with a fresh empty database.

Sometimes you don’t even need a database, you just want to display a list of customers in a grid to show your audience something, so, lets assume you have a Customer class that has the following definition

public class Customer
    {
        public int Id { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string Genger { get; set; }
        public string PhoneNumber { get; set; }
        public string Address { get; set; }
        public DateTime BirthDate { get; set; }
    }

You would normally do the following in your code:

 public ActionResult Index()
        {
            var listOfCustomers = new List<Customer>();

            listOfCustomers.Add(new Customer { Id = 1, FirstName = "John", LastName = "Smith", Address = "Someaddress", BirthDate = DateTime.Now.Subtract(TimeSpan.FromDays(9000)) });
            listOfCustomers.Add(new Customer { Id = 1, FirstName = "Mark", LastName = "Johnson", Address = "Someaddress", BirthDate = DateTime.Now.Subtract(TimeSpan.FromDays(9000)) });
            listOfCustomers.Add(new Customer { Id = 1, FirstName = "Jackson", LastName = "Clark", Address = "Someaddress", BirthDate = DateTime.Now.Subtract(TimeSpan.FromDays(9000)) });
            listOfCustomers.Add(new Customer { Id = 1, FirstName = "Emillia", LastName = "Smith", Address = "Someaddress", BirthDate = DateTime.Now.Subtract(TimeSpan.FromDays(9000)) });

            return View(listOfCustomers);
        }

And the results would be:

list of customers

Seems good but not very satisfying and requires a lot of work specially if you want to show a lot of records to have paging for example.

GenFu is a very exciting library that can save you all this time, it uses code to generate real-time person information including names, address, birth date  and a lot more.

To use GenFu, all you have to do is to install its package using NuGet package manager, so  from VS, select tools -> NuGet Package Manager -> Package Manager Console and type the following command

install-package GenFu

Then replace the code written above to create list of customers with the following code:

  public ActionResult Index()
        {
            var listOfCustomers = A.ListOf<Customer>(20);

            return View(listOfCustomers);
        }

With just one line of code, it will create a 20 records with real data, and the results will be like this:

list of customers with genfu.PNG

 

To use GenFu to pre fill your database with some records, you can add the same line of code inside the Seed method in your Migration class, just like below

 
 internal sealed class Configuration : DbMigrationsConfiguration<GenFuDemo.Models.CustomersContext>
    {
        public Configuration()
        {
            AutomaticMigrationsEnabled = false;
        }

        protected override void Seed(GenFuDemo.Models.CustomersContext context)
        {
            context.Customers.AddOrUpdate(c => c.FirstName, A.ListOf<Customer>(20).ToArray());
        }
    }

This method will run when you run the update-database command and the data will be inserted into the Customer table

To read more about GenFu, you can visit its GitHub repository, it offers more features like customizing the way it generates or giving hints about some properties that it may not understand, for ex: if you have a property named NightNumber, which is a phone number, in this case you can instruct GenFu using its Fluent APIs to generate phone numbers for the property NightNumber

Building a LOB application with MVC 5 – Part 5 – Views

This is the sixth part of building line of business application using MVC 5, you can read the previous parts through the following links

  1. Building a LOB application with MVC 5 – Part 0
  2. Building a LOB application with MVC 5 – Part 1
  3. Building a LOB application with MVC 5 – Part 2 – Models and Generic Repository
  4. Building a LOB application with MVC 5 – Part 3 – EntityFramework
  5. Building a LOB application with MVC 5 – Part 4 – Controllers, Routes and Areas

In the previous part, we introduced controllers, routes and areas and we created the needed controllers and areas.

In this part, we will introduce views, so by the end of this post, we will finally have something that we can see.

What are Views?

We talked about the M and C, so we have the V from MVC remaining, in web forms, we mainly have the logic and view in one place (aspx), but in MVC, the presentation of the your data is the responsibility of the View, your controller intercept the request, call the business logic, and select how it wants to display the data.

You can display it as a text, Image, Chart, HTML or a downloadable file, in web forms you would have to create a separate web form for each view, but in MVC, you only have to duplicate the view part.

So, for now, lets just say that Views are this pieces that we see the system through it, it used to display the  information passed to it from the controller to the users and capture information from the users and forward it to the controller for updates

What is View Engine?

When MVC was released, the views were aspx pages and you had to write these annoying opening and closing tags from web forms era, but later you had the option to either use web forms rendering or the new views engine called Razor.

Razor is much more clean way of writing your views, basically it is all HTML unless you started with @ symbol, this is where the compiler assumes that you want to have a server side code

The View Engine is responsible for translating the written code either in aspx or Razor syntax and produce the final HTML, you can access the list of installed view engines by calling the  ViewEngines.Engines property, you can also add a new custom engine to this list by implementing the interface IViewEngine.

As you can see below, MVC 5 is shipped with 2 view engines

  1. WebFormViewEngine which renders the ASPX pages into HTML
  2. RazorViewEngine which renders the .cshtml files used in razor to HTML

view engines.PNG

When you expand the RazorViewEngine, you will see the following:

razor view engine details.PNG

As you can see above and as we stated in previous posts, MVC uses conventions over configuration, so by default the controller action will search for a view with the same action name inside a folder with the same controller name without the word Controller inside the Views folder, you can change these conventions by editing the corresponding property in the view engine and make sure to add this code in the Global.asax to make sure it is executed first thing when the application starts.

Layout Page (Master Page)

MVC has the same concept of Master page in web forms, only it is called Layout page here, by default the layout is set for any view unless you set the property Layout to null as below

layout null

if you didn’t do that, then the view will inherit the default Layout which is by convention again resides in Views\Shared\_Layout.cshtml

You can have more than one layout in your project, and you can set the layout for the view by setting the Layout property to the custom layout path, ex:


Layout = "~/Views/Shared/_CustomLayoutPage.cshtml";

Razor Syntax

Razor syntax is very similar to normal HTML unless when it starts with @ symbol, to have more details about it, please read more from microsoft site Razor Syntax

Passing data from Controllers to views

Since the view will be displaying data to the end users, we nee to pass this data from the controllers into the view, this happens in 2 ways

Strongly Typed Views

With strongly typed views, the view knows what is the data type of the model and you can reference the properties of the model inside your view code by using the Model property, visual studio supports  intellisense for this.

you can set the model type for the view by adding the following lines at the begenning of the view

@model AppointmentManager.Web.Models.AddPhoneNumberViewModel

To see it in action, you can open the file \Views\Manage\AddPhoneNumber.cshtml and examine the code

You can pass the data from your action to the view by adding the model object into the View method as below, if you used View() without any value and tried to access the Model  object inside the view, it will throw a null exception

pass model to view.PNG

Weakly Typed Views

In this type, you don’t specify the type of the model, you just pass the data you need to the view using 3 predefined properties:

  1. ViewBag, this is a dynamic object, so you can simply write ViewBag.Message = “Hello” in your action and in the view you can read it by adding @ViewBag.Message, the ViewBag variables are available only for the current view, so if you have an action called Index and you set a message variable inside it, you can access it only in the Index view, if you navigated to another action, then you can’t access it from there
  2. ViewData, this is the same as the ViewBag except it is a dictionay, so to add a key to it from your controller you either use ViewData.Add(“Key”,”Value”), or you can simply write ViewData[“Key”]=”value” and in your view just write @ViewData[“Key”]
  3. TempData, this is the same as teh ViewBag except that its lifecycle is a little bit longer, you can access it from the next action, so if you set the value of a variable called Message in your Create action that is called when the user post a form then you redirected to the Index action, you can then call teh Message variable from the Index action, this can be used to show a confirmation message when the user is redirected fom a page to another, note that after the redirection, the variable will be lost, so you can’t use it again.

Create Views

To create a view, you can go select the folder inside the Views folder where you want to add your view, right click and select Add -> View

Or you can go to your controller, put the cursor inside the action that you wants to generate view for it, and right click then select Add View.

Lets do that together.

Expand Areas, then Admin, right click Controllers and add an Empty Controller named ServiceTypes, this will be used to administer service types.

Add a project reference to the following projects inside the web project

  1. AppointmentManager.Models
  2. AppointmentManager.Repository
  3. AppointmentManager.Repository.EntityFramework

Right Click inside the Index action and choose Add View, leave the view name as is to avoid writing the name explicitly inside the action, choose the template as List, this will create a listing page, you can find the rest of templates for CRUD operations, select the model class that VS will use to generate the view using scaffolding technique, you can choose the Layout page then click Add

create view
Once done, the generated view file will be opened in VS and you can inspect the code, the first thing you will notice is the word @Html is mentioned a lot

HTML Helpers

If you have a form that accepts a username and password, you can write it as below

<input type="text" name="username" id="username" value="" />
<input type="password" name="password" id="password" value="" />

And if the model property was changed then you have to revist your HTML and update it to be the same as your model, also this is a lot of code to be written, so MVC offrers HTML helpers to save your time, the above code can be replaced by:

 @Html.TextBoxFor(m => m.Email)
 @Html.LabelFor(m => m.Password)

The above code will generate the same code and you can add more properties like css classes and other attributes.

To read more about HTML helpers and how you can create your own helpers, please visit this link

 

Model Binding

Now, the user browsed to your application, clicked register, and he is redirected now to the /Account/Register which means the account controller and register action, we have a register view which draws some input fields to capture the user information, the user adds the required information and clicked Submit.

In web forms, we used to do a lot of person.Name = txtName.Text

But in MVC, we don’t have to do that as MVC does it for us using something called Model Binding

When your action accepts a parameter and the user submit an request to this action, MVC automatically create an instance of this object and start to fill its properties from the request body, query string, route values, all these sources called Value Providers, you can add a custom value provider by going through the following post

MVC fill the object properties with request parameters that has the same name, so, if you have a class called Customer, and inside it you have FirstName and LastName, then MVC inspect the request for a query string or form values with the same names.

If the default model binder doesn’t meet your expectations, you can create your own, to read more please see MVC Model Binders

Scaffolding

Remember when we added a view and chose the template type as List and the model type as ServiceType and suddenly we have a listing screen? this is called Scaffolding and it happens using T4 Templates that visual studio runs.

To customize these templates, you have to do the following:

  1. Open C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\Extensions\Microsoft\Web\Mvc\Scaffolding\Templates
  2. Create a folder called CodeTemplates in the web project root directory
  3. Copy the template you want into this folder and customize it, ex: MvcControllerEmpty, open it and customize it the way you want.

After that, create a new item from this template by following the same normal procedure, Right Click the project file-> Add -> New

You will see the updates you made applied to the newly created file, VS is smart enough to override the template with the one in your project.

Annotations and Validations

HTML Helpers can use any annotation attributes defined for each class property and it will use it generate the correct input control and add the right validation.

Ex: When we add the Required, MaxLength and Display attribute to the Name property inside the Country class, it will generate an extra validation for the textbox generated in the view, it will make the field required and has a max length of 50 charactres, it will also change the label from Name to Country Name

annotation

Not only this, but it will also impact the EntityFramework code first, when you run the application, EF will compare the model with the database and finds that the Name property has been changed and ti will ask you to add another migration in order to mark the Name column as Required and has a max length of 50

The same will apply when the ViewState.IsValid property is called in the Controller Action, this will make your validation consistent from the UI layer up to the data access layer.

Imagine if you followed the first way of adding just plain HTML code like the example above, you would have to add all the validation yourself, but now HTML helpers removed all this burden

You can now go ahead and generate views and add annotations for all the entities and controllers, if you have any questions, please leave a commant

 

You can get the full source code from GitHub Repository https://github.com/haitham-shaddad/AppointmentManager

Azure Services and Components

In the previous post What is Microsoft Azure? we introduced azure and cloud computing in general, we also explained how can we signup for an account using either the free trial or MS Dev Essentials.

In this post, I will explain the different parts and services in Azure.

How are services grouped in Azure?

Azure has different services for different needs, it can be organized in many ways as below

Services

  1. Compute
  2. Storage
  3. Networking
  4. Integration

Layers

  1. Application
  2. Data
  3. Integration

We can also divide it according to the consumption model (IAAS, PAAS, or SAAS), but we will stick to the above categorization for now

In this post, we will only explain the services part

Compute

This category has many wonderful services, like Virtual machines, Cloud Services which is a type of a virtual machine but more manageable by Azure and it has 2 types, web role used to host web sites and a worker role to host other code that runs on any windows machine.

Compute also has App service which as a developer you will be always using it as it offers everything you can wish for, starting from databases to DevOps, App Service has the following features

  1. Web App, similar to cloud service but it is more PAAS and lightweight, the same web app can be used to host both a web application and a timer job using Web Jobs, note that it has been always called Azure web sites, so if you heard that name, don’t be confused, it is the same
  2. Mobile App, as the name implies, it is a backend as a service for your mobile application, it offers a lot of features like a storage for your data, authentication, offline sync and push notification, it has also been known by Azure Mobile Services for long time
  3. Logic App, used to build a workflow applications to handle different business logic scenarios, ex: receive a message, post an order to the inventory service, sends an email, assign a task to shipping employee …, the logic app is based on BizTalk services which is an online version from BizTalk server
  4. API App, used to host REST APIs with a lot of features like throttling, payment for usage, reports …

Storage

This is one of the most important services in Azure and without it, you can nearly do nothing, this is used for storing anything starting from simple files, VM VHD files to databases.

Storage is divided into storage accounts, each account can hold upto 500 TB, with some limits on the number of operations per second, to know more about Azure services limits you can read more from this link

You can create more than one account and use it for different services, ex: you can have an account for your databases and another for virtual machines , but you have to take care of the limits to avoid any issues

Networking

Azure enables you to create VPN  just like on-premise and only virtual machines, web apps or any other services joined to the VPN can see each other, not only this, but you can join the VPN to on-premise VPN in any of the following ways

  1. Site to Site: this will join a whole VPN on-premise to Azure VPN, think of it as if you are expanding your datacenter
  2. Point to Site: this will join a single machine on-premise to Azure VPN

Integration

This feature allows you to integrate applications deployed on Azure with other applications running on-premise or even on Azure using BizTalk services.

 

There are a lot of other services like Azure Active Directory, SQL Database, DocumentDB, Search, I will write about these services in next post, then I will start a series where we will build an application and utilize most of azure services in one place.

 

If you have any suggestions about it, please leave a comment.

 

Building a LOB application with MVC 5 – Part 4 – Controllers, Routes and Areas

This is the fifth part of building line of business application using MVC 5, you can read the previous parts through the following links

  1. Building a LOB application with MVC 5 – Part 0
  2. Building a LOB application with MVC 5 – Part 1
  3. Building a LOB application with MVC 5 – Part 2 – Models and Generic Repository
  4. Building a LOB application with MVC 5 – Part 3 – EntityFramework

In the previous part, we introduced EntityFramework code first migration and created the generic repository using EF, then we applied the migration to create a database and ran some unit tests to make sure our Repository layer is working fine.

In this part, we will introduce Controllers, routes and areas

MVC Controllers

The “C” in MVC, if you recall some design patters, you may heard of the Front Controller pattern, this is basically the guy at the front door who receives the request, validate it, call whatever services for you and later forward you to the suitable view.

To understand how controllers work and how the URL you type in the browser is mapped to a piece of code, lets see how the MVC application life-cycle works, but take into consideration that MVC is based on the same System.Web used in Web Forms, so they share some life cycle events

  1. A request is received by the IIS Server and forwarded to an MVC handler, this is a normal HTTP handler
  2. MVC handler gets the request and invokes the routing API which we will explain later and it examines the route table to see which controller and action should handles the request
  3. The MVC handlers creates the controller using the method CreateController from the interface IControllerFactory, the default implementation for this interface is DefaultControllerFactory, it simply create a new instance from the controller class, if your controller constructor doesn’t have parameter-less constructor, this method will fail and throw and exception, later when we see dependency injection, we will see how to override the default controller factory by calling ControllerBuilder.Current.SetDefaultControllerFactory in Application_Start in Global.asax.cs
  4.  Invoke authentication filters, we will read more about filters and authentication in future posts
  5. Bind query string parameters, form values and route values to the action method parameters using the default model binder, we will see later how to build custom model binders
  6. Invoke the action and action filters
  7. Execute the results(View, Content, Empty, JSON, File) and any result filters
  8. Send the response to the user

You can read more about the MVC Application Life-Cycle here

Convention over Configuration

You can think of a controller as a way to group a module features together in one place, for ex: a CustomerController will have all the code related to Customers like Browse Services, view service details ..

By Default MVC 5 works with the convention over configuration model, it means you will not find a code that maps the exact URL to the exact controller name and action, nor you will find a config that tells how to relate the action name with the view page, this is all following a specific convention.

  1. URL mapping to controllers and actions is configured using routing template
  2. Every controller in the controllers folder will have a folder inside the Views folder with the same name without “Controller” word
  3. Every action inside  controller will have  a view inside the Views\controller folder with the action name unless you specified another view name explicitly

Now, lets create some controllers that will be used in out Appointment Manager application

  1. In the AppointmentManager.Web project, right click the Controllers folder and choose Add -> Controlleradd controller.PNG
  2. You have 3 options, either an empty controller which is self explanatory , with read/write actions which is created with some get, post, delete and put methods, and the last one is used when you have an entity framework context inside your web project which is not recommended, this option created a CRUD controller for the selected entity, ex: if you selected our DB Context and choose the entity as Appointment, then it will generate CRUD for the appointment class, in our case, we will choose Empty
  3. Enter the name as “Customers” and Click Add, this will create an empty controller with a single action called Index

If you have a look at the Index action, you will find it has some few properties

 public ActionResult Index()
        {
            return View();
        }
  1. The method is public
  2. The return type is ActionResult or anything that inherits from IActionResult
  3. It used a helper method called View to return an object that inhers from ActionResult , there are many other help functions like File(), Json(), Empty()

By default the action has no view, and if you run the application now and navigated to http://localhost:16106/Customers/, you will have the following screen, your application may be running on a different port

view not found.PNG

This is the convention over configuration part, it tried to find a view with the name Index which is the action name in the path View/Customers and Views/Shared, and since we didn’t specify a view name in the return View() method, then it fails.

To create a view, you can either go to related view folder for your controller and create a view with the same name as the action using Right Click, Add new item, and Select view.

or you can just right click in the action method and choose “Add View”

Now, Lets create the needed controllers along with its actions and views

  1. Customers
    1. Services
    2. Providers
    3. ProviderDetails
    4. BookAppointment
    5. Calendar
  2. ServiceProviders
    1. Calendar
    2. AppointmentDetails
    3. ManageServices
    4. AvailableTime

Create empty view for each action, after you are done, your views folder should be the same as below, you can of course change the name as you like, and you can now navigate to each path and make sure it opens without errors, the path should be controller name/action name, ex: Customers/Calendar

views.PNG

Routes

When we opened the URL http://localhost:16106/Customers, it automatically knew that URL should be handled by the Customes controller, the Index method, this is configured in the file App_Start\RouteConfig.cs

This is the content of the file:

 public class RouteConfig
    {
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

            routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{id}",
                defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
            );
        }
    }

the most important line is the one that defines the “Default” route, you can find the url property that has the value “{controller}/{action}/{id}”, and the line below it, it specifies default values from these placeholders, in this case if the URL was http://localhost:16106/ without anything else, this means the controller will be HomeController, and if you specify  the controller but no action, like the case in http://localhost:16106/Customers, then, the action will have the default value “Index” which why the Index action is called when we didn’t specify it.

You can add as many routes as you want, but make sure to make the most specific at the top, think of it like exception handing, if you put a try and catch and inside the catch you put the root Exception class, then any other catches will not be called as the Exception class will map to all exceptions.

ex:

 routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{id}",
                defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
            );

            routes.MapRoute(
               name: "Calendar",
               url: "Calendar",
               defaults: new { controller = "Customers", action = "Calendar", id = UrlParameter.Optional }
           );

In this case, the calendar route will never get a chance to fire, because the path: /calendar will be alreayd cought by the default route and the controller will be mapped to Calendar and you will find an exception that it can’t find any controller with the name Calendar, so you have to put the calendar route before the default route

There is also Attribute based routeing, where you simply put an attriibute before the action name or controller name like the below

 [Route(template:"Customers/BrowseServices")]
        public ActionResult Services()
        {
            return View();
        }

You can read more about attribute based route here on asp.net site 

Areas

You noticed that we didn’t add a controller for the admin side, but in the admin case, we will have many controllers, ex: Services, ServiceCategories, Users …

It will be like a sub project, how can we isolate it from the rest of the project?

The answer is MVC Areas, it helps us to isolate business domains in a separate folder that can be handled by separate teams, in an eCommerce scenario, we would have an area for Shopping cart, another for inventory management, and another one for shipping

To create an area, right click the project itself and choose Add => Area and type Admin as the area name and click Add, you will have a new folder called Areas and inside it you will have the folder Admin and just inside this folder you will have the same project structure

area

create the following controllers inside the Admin area, to do that, follow the same instructions that we used to create the customers  and service providers controllers but this time select the controllers folder inside the admin area

  1. Services
  2. ServiceCategories
  3. Users
  4. Reports

 

So far, we created the needed controllers, routes, and views, in the next post, we will start working on the views and add some UI that makes the application life.

 

You can get the full source code from GitHub Repository https://github.com/haitham-shaddad/AppointmentManager

SharePoint 2013 Search not working for anonymous users

We had a public site that has a lot of Content Search web parts, everything was working fine but suddenly search web parts stopped working only for anonymous users and was working fine for logged in users.

After some Googling and full crawling, I managed to get it working using the following PowerShell Script, I had run it for every list and library that search read data from

 

#Add-PSSnapin microsoft.sharepoint.powershell
cls
 $web = get-spweb "http://your server"
 $web
$list = $web.Lists["List Title"]
$list
$list.BreakRoleInheritance($true)

$list.AnonymousPermMask = $list.AnonymousPermMask -bor ([int][Microsoft.SharePoint.SPBasePermissions]::ViewFormPages) #binary or adding the permissions

$list.Update()

 

 

Building a LOB application with MVC 5 – Part 3 – EntityFramework

This is the fourth part of building line of business application using MVC 5, you can read the previous parts through the following links

  1. Building a LOB application with MVC 5 – Part 0
  2. Building a LOB application with MVC 5 – Part 1
  3. Building a LOB application with MVC 5 – Part 2 – Models and Generic Repository

In the previous part, we created all the model objects, a Generic repository interface and a generic service layer interface with its implementation.

In this part, we will build the generic repository implementation using EntityFramework 6, and before we proceed, I will introduce EntityFramework first.

What is EntityFramework?

EntityFramework is Microsoft’s Object Relational Mapper (ORM) framework, it is used to map objects to database tables and vice versa, it uses mapping file or metadata to generate a dynamic SQL at run time.

This is a different model than the one we used to do, which basically depend on Stored Procedures and code generation tools to save time, there is a debate regarding performance of dynamic SQL against compiled stored procedures, but in my point of view, this is not a major concern now and you can utilize caching to overcome the difference, besides, with EntityFramework you can still utilize Stored Procedures for important operations that may need special performance needs.

EntityFramework Usage Models

EntityFramework can be used in 3 ways

  1. Database First: Start with the database, and use it to generate code, this model should not be used for new projects, it is not flexible as you can’t edit the generated code directly but through a partial classes and all the mapping exist in a single file which make it hard to share between team members if more than one wants to apply changes at the same time.
  2. Model First: Start with a model and design the entities, attributes and its relationships, use this model to generate both the classes and database, once this happened for the first time, it will be the same as Database First
  3. Code First: Start with a pure classes and then use something called Migration to generate the database, this model is the recommended way to go and EF 7 has no database first model, it is all about Code First now, with Code First, you can have snapshots of your code and database, and you can rollback at any point to any previous version.

Build the Generic Repository

To start generating our generic Repository implementation, we will add the EntityFramework package to the AppointmentManager.Repository.EntityFramework project as this will be our repository project.

In order to do that, we will use NuGet which is a package manager for .Net, we use it to install, uninstall and update packages instead of referencing DLL files directly from a shared folder, the package can be a simple DLL or code file, JavaScript, special configuration or entries in web.config

To install the package, Click Tools -> NuGet Package Manager -> Package Manager Console

Make sure “AppointmentManager.Repository.EntityFramework” is selected in the default project drop down list, then type the following command and press enter

install-package EntityFramework
NuGet EntityFramework

In the project  “AppointmentManager.Repository.EntityFramework”, do the following:

  1. Add Reference to “AppointmentManager.Repository”  and “AppointmentManager.Models”
  2. Add a new class named EFRepository
public class EFRepository<T, K> : IRepository<T, K> where T : class
    {
        private DbContext _context;
        private DbSet<T> _entitySet;

        public EFRepository(DbContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            this._context = context;
            _entitySet = _context.Set<T>();
        }

        public T Add(T item)
        {
            _entitySet.Add(item);
            _context.SaveChanges();
            return item;
        }

        public bool Delete(T item)
        {
            _entitySet.Attach(item);
            _entitySet.Remove(item);
            _context.SaveChanges();
            return true;
        }

        public bool DeleteByID(K id)
        {
            var item = _entitySet.Find(id);
            _entitySet.Remove(item);
            _context.SaveChanges();
            return true;
        }

        public T GetByID(K id)
        {
            return _entitySet.Find(id);
        }

        public IQueryable<T> GetAll()
        {
            return _entitySet;
        }

        public IQueryable<T> GetAll(Expression<Func<T, K>> orderBy)
        {
            return _entitySet.OrderBy(orderBy);
        }

        public IQueryable<T> GetAll(int pageIndex, int pageSize)
        {
            return _entitySet.Skip((pageIndex - 1) * pageSize).Take(pageSize);
        }

        public IQueryable<T> GetAll(int pageIndex, int pageSize, Expression<Func<T, K>> orderBy)
        {
            return _entitySet.Skip((pageIndex - 1) * pageSize).Take(pageSize).OrderBy(orderBy);
        }

        public IQueryable<T> Find(Expression<Func<T, bool>> predicate)
        {
            return _entitySet.Where(predicate);
        }

        public IQueryable<T> Find(Expression<Func<T, bool>> predicate, int pageIndex, int pageSize, Expression<Func<T, K>> orderBy)
        {
            return _entitySet.Where(predicate).Skip((pageIndex - 1) * pageSize).Take(pageSize).OrderBy(orderBy);
        }

        public bool Update(T item)
        {
            _entitySet.Attach(item);
            _context.SaveChanges();
            return true;
        }
    }
 

Build the project and make sure it compiles successfully

Add a new class called AppointmentManagerContext, this class is needed only for the migration to work, we will not be using it as the EFRepository class is using the base DbContext class, you can still change it and add properties of type DbSet<T> for each entity in the application, this will be helpful specially if you want to do some joins between different entities.

 public class AppointmentManagerContext : DbContext
    {
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Entity<User>()
             .Map<Customer>(m =>
             {
                 m.Requires("UserType").HasValue((int)UserRole.Customer);
                 m.ToTable("Users");
             }
             ).Map<ServiceProvider>(m =>
               {
                   m.Requires("UserType").HasValue((int)UserRole.ServiceProvider);
                   m.ToTable("Users");
               }
               )
               .ToTable("Users");

            modelBuilder.Entity<ServiceProviderReview>().HasRequired<Appointment>(a => a.Appointment);

            base.OnModelCreating(modelBuilder);
        }
    }

After that, we need to generate our database using Code First Migration, open the Package manager console and type the following command, make sure the project AppointmentManager.Repository.EntityFramework is selected

Enable-Migrations

You may encounter an issue regarding the TimeSlot class that it has no key defined, just add an integer property called ID to this class and rerun the command again
Then run the following command to add the first migration which will compare the model classes to the database and add code to generate the database, later when we add new classes or properties, we will run the command again which will add another migration that will generate code to add the new properties to the database.

Add-Migration -Name Initial

After running the command, you will notice that a new class named Initial_[time].cs, where [time] is the date time for the time the file was generated

migration.PNG

Before we proceed, I would like to explain the content for the method OnModelCreating:

Since we have all classes inheriting from the BusinessEntity class, and we have the Customer and ServiceProvider classes inherit from the User class, we must tell EntityFramework how it will generate tables for these classes.

By default, EntityFramework will generate a new class for each entity with its properties including these properties of the parent class which is fine in the BusinessEntity class as we want all common properties like ID and CreationDate to exist in all tables.

But for the Customer and ServiceProvider classes, we need a table per hierarchy, both classes must be mapped to a single table called Users, to do that, we added the code at line 5 where we tell EF to map the User class to another 2 sub-classes and for each one we told it to use the same table name “Users”, this way EF will combine the properties of the 3 classes and add it to one table.

There are another 2 types of inheritance, table per type (TPT), in our case, it would have been 3 tables (User, ServiceProvider and Customer), The third option is table per class (TPC) which will generate only 2 tables (ServiceProvider and Cutomer) and each table will have the properties in the parent User class.

So far, we still don’t have our database created, and to do that, we will have to run this command in the package manager console

Update-Database

After you do, you will have the following error

Introducing FOREIGN KEY constraint 'FK_dbo.Appointments_dbo.Users_ServiceProviderID' on table 'Appointments' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.
Could not create constraint or index. See previous errors.

This is the time we will have to change the generated migration Initial file manually to override the cascade action.

Open the intiial file, in line 70 and line 148, change cacadeDelete to false and run the update-database command again

Now we have our backend ready, and the database is created, but we didn’t specify any connection strings, so where has been the database created? by default there is a connection string named DefaultConnection and it reference the localdb database, so open management studio and connect to server (localdb)\mssqllocaldb

you should find the database created with the name of the context class, if you want to override that, you can add a connection string named Defaultconnection in the project configuration file with the database name and server you want and then run the update-database command again.

db.PNG

 

Lets make sure now our backend is working fine, create a new unit test project and name it “AppointmentManager.Repository.EntityFramework.Test”

Add reference to the following projects:

  1. AppointmentManager.Repository.EntityFramework
  2. AppointmentManager.Repository
  3. AppointmentManager.Models

Rename the default file “UnitTest1” to GenericRepositoryTest

Rename the default method to TestInsertion and put the following code

[TestClass]
    public class GenericRepositoryTest
    {
        [TestMethod]
        public void TestInsertion()
        {
            var context = new AppointmentManagerContext();
            IRepository<ServiceType, int> serviceRepository = new EFRepository<ServiceType, int>(context);

            var serviceType = new ServiceType()
            {
                CreatedBy = "admin",
                CreationDate = DateTime.Now,
                LastModificationDate = DateTime.Now,
                Name = "Test service"
            };

            serviceType = serviceRepository.Add(serviceType);

            Assert.IsNotNull(serviceType);
            Assert.AreNotEqual(serviceType.ID, 0);

            serviceType = serviceRepository.GetByID(serviceType.ID);
            Assert.IsNotNull(serviceType);

            serviceRepository.Delete(serviceType);
            serviceType = serviceRepository.GetByID(serviceType.ID);
            Assert.IsNull(serviceType);
        }
    }

Right click the method in VS and choose Run Tets and make sure the test succeeds, you can double check by putting a break point before the line that deletes the serviceType object and check the database and ensure the record is there

By this, we have a read repository that we can use to manage our data, in the next part we will start building the UI.

 

You can get the full source code from GitHub Repository https://github.com/haitham-shaddad/AppointmentManager