Creation Web API solution
First of All, we need to create a new .NET Core application project witch called “Forms.WebAPI”. After that, we add the different concerns in this solution:
In this videos, you will learn how to:
- Create Asp.NET Core web API.
- Entity Framework Code First.
- Using Swagger framework.
- GitHub code
- BLL (Solution Folder)
- Forms.Managers
- DAL (Solution Folder)
- Forms.DA
- Forms.Repositories
- ML (Solution Folder)
- Forms.Enums
- Forms.Models
On the Forms.DA project, you navigate to Nuget manager and install this packages:
Let’s add now the database context class “FormsContext”:
using Forms.Models;
using Microsoft.EntityFrameworkCore;
namespace Forms.DA
{
public class FormsContext : DbContext
{
public FormsContext() : base()
{
}
public DbSet<UserModel> Users { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer("Data Source=(LocalDb)\\MSSQLLocalDB;Initial Catalog=Forms;Integrated Security=SSPI;");
}
}
}
And the UserModel class:
namespace Forms.Models
{
public class UserModel: BaseModel
{
/// <summary>
/// Gets or sets the FirstName.
/// </summary>
public string FristName { get; set; }
/// <summary>
/// Gets or sets the LastName.
/// </summary>
public string LastName { get; set; }
/// <summary>
/// Gets or sets the Email.
/// </summary>
public string Email { get; set; }
/// <summary>
/// Gets or sets the password.
/// </summary>
public string Password { get; set; }
/// <summary>
/// Gets or sets the mobile number.
/// </summary>
public string MobileNumber { get; set; }
}
}
Finally, we declare the “IUserRepository.cs” interface in “Interfaces” folder :
using Forms.Models;
using Forms.Repositories.Repositories.Interfaces;
namespace Forms.Repositories.Interfaces
{
public interface IUsersRepository : IGenericRepository<UserModel>
{
}
}
and “UserRepository .cs” calss:
using Forms.DA;
using Forms.Models;
using Forms.Repositories.Commun;
using Forms.Repositories.Interfaces;
namespace Forms.Repositories
{
public class UsersRepository : GenericRepository<UserModel>, IUsersRepository
{
public UsersRepository(FormsContext context)
: base(context)
{
}
}
Creation Database:
In order to create the database we need to run power shell command:
Let’s navigate to the “package manager console” in Tools menu and run:
Add-Database Initial
This command generate a Migration folder in Forms.DA project witch contains a generated C# code represents the queries to lunched for creation tables.
Let’s execute this queries on database by running this command:
Update-Database
If you connect to the database, you will see:
Adding Generic Repositories:
Generic repository is a design pattern, user to make the different CRUD operations, it’s allows :
– Defines a common behavior of the entities.
– Avoid code duplication.
When an entity needs to define a specific behavior, it inherits the common behavior and then redefines the specification
Let’s create the Interface called “IGenericRepository.cs” in Forms.Repositories project in “Interfaces” folder :
namespace Forms.Repositories.Repositories.Interfaces
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
/// <summary>
/// The GenericRepository contract.
/// </summary>
/// <typeparam name="TEntity">Entity type.</typeparam>
public interface IGenericRepository<TEntity>
where TEntity : class
{
/// <summary>
/// Gets entities.
/// </summary>
/// <param name="filter">The filter to apply.</param>
/// <param name="orderBy">The order by to apply.</param>
/// <param name="includeProperties">includerd properties.</param>
/// <returns>The query result.</returns>
IEnumerable<TEntity> Get(
Expression<Func<TEntity, bool>> filter = null,
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
string includeProperties = "");
/// <summary>
/// Get object from table by id.
/// </summary>
/// <param name="id">The object id.</param>
/// <returns>The query result.</returns>
TEntity GetByID(object id);
/// <summary>
/// Inset entity in table.
/// </summary>
/// <param name="entity">The entity to insert.</param>
/// <returns>The created item Id.</returns>
long Insert(TEntity entity);
/// <summary>
/// Delete entity by id.
/// </summary>
/// <param name="id">The entity id.</param>
void Delete(object id);
/// <summary>
/// Delete entity.
/// </summary>
/// <param name="entityToDelete">The entity to delete.</param>
void Delete(TEntity entityToDelete);
/// <summary>
/// Update entity.
/// </summary>
/// <param name="entityToUpdate">The entity updated.</param>
void Update(TEntity entityToUpdate);
/// <summary>
/// Update all entities.
/// </summary>
/// <param name="entitiesToUpdate">The entities list to update.</param>
void UpdateAll(IEnumerable<TEntity> entitiesToUpdate);
}
}
and a class called “GenericRepository.cs” in “Common” Folder :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using Forms.DA;
using Forms.Models;
using Forms.Repositories.Repositories.Interfaces;
using Microsoft.EntityFrameworkCore;
namespace Forms.Repositories.Commun
{
public class GenericRepository<TEntity> : IGenericRepository<TEntity>
where TEntity : BaseModel
{
protected FormsContext DbCxt;
protected DbSet<TEntity> DbSet;
public GenericRepository(FormsContext context)
{
DbCxt = context;
DbSet = context.Set<TEntity>();
}
public void Delete(object id)
{
TEntity entityToDelete = DbSet.Find(id);
this.Delete(entityToDelete);
}
public void Delete(TEntity entityToDelete)
{
if (DbCxt.Entry(entityToDelete).State == EntityState.Detached)
{
DbSet.Attach(entityToDelete);
}
DbSet.Remove(entityToDelete);
}
public IEnumerable<TEntity> Get(Expression<Func<TEntity, bool>> filter = null, Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null, string includeProperties = "")
{
IQueryable<TEntity> query = DbSet;
if (filter != null)
{
query = query.Where(filter);
}
foreach (var includeProperty in includeProperties.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
{
query = query.Include(includeProperty);
}
if(orderBy != null)
{
return orderBy(query).ToList();
}
else
{
return query.ToList();
}
}
public TEntity GetByID(object id)
{
return DbSet.Find(id);
}
public long Insert(TEntity entity)
{
DbSet.Add(entity);
return entity.Id;
}
public void Update(TEntity entityToUpdate)
{
DbSet.Attach(entityToUpdate);
DbCxt.Entry(entityToUpdate).State = EntityState.Modified;
}
public void UpdateAll(IEnumerable<TEntity> entitiesToUpdate)
{
foreach (var entity in entitiesToUpdate)
{
this.Update(entity);
}
}
}
}
Adding UnitOfWork:
UnitOfWork is a desgin pattern responsible for saving changes in database after making Insert, Delete or Update operations. It ensures the smooth execution of the transaction on database.
Among the common mistakes, make SaveChanges in Repository, it’s not its job.
So let’s add the interface “IUnitOfWork.cs” in Interfaces folder:
namespace Forms.Repositories.Interfaces
{
public interface IUnitOfWork
{
void Commit();
}
}
and “UnitOfWork.cs” in “Common” folder:
using Forms.DA;
using Forms.Repositories.Interfaces;
using System;
namespace Forms.Repositories.Commun
{
public class UnitOfWork : IUnitOfWork, IDisposable
{
private FormsContext dbContext;
private bool disposed = false;
public UnitOfWork(FormsContext context)
{
dbContext = context;
}
public void Commit()
{
dbContext.SaveChanges();
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool isDisposed)
{
if(!disposed)
{
if (!isDisposed)
{
dbContext.Dispose();
}
}
disposed = true;
}
}
}
Adding Managers
So the managers project represents the Business logic layer. Simply, it contains all the business rules.
Let’s define a “BaseManager.cs” class in witch we can put all the common properties or methods that can be used by all managers.
using Forms.Repositories.Interfaces;
namespace Forms.Managers.Commun
{
public class BaseManager
{
private readonly IUnitOfWork unitOfWork;
public BaseManager(IUnitOfWork unitOfWork)
{
this.unitOfWork = unitOfWork;
}
protected IUnitOfWork UnitOfWork => unitOfWork;
}
}
Finally, we add the “IUersManager.cs”
using Forms.Models;
using System.Collections.Generic;
namespace Forms.Managers.Interfaces
{
public interface IUsersManager
{
UserModel GetUserById(int id);
IEnumerable<UserModel> GetUsers();
long InsertUser(UserModel userModel);
}
}
And its class “UsersManager.cs”
using Forms.Managers.Commun;
using Forms.Managers.Interfaces;
using Forms.Models;
using Forms.Repositories.Interfaces;
using System.Collections.Generic;
namespace Forms.Managers
{
public class UsersManager : BaseManager, IUsersManager
{
private readonly IUsersRepository usersRepository;
public UsersManager(IUsersRepository usersRepository, IUnitOfWork unitOfWork)
: base(unitOfWork)
{
this.usersRepository = usersRepository;
}
public UserModel GetUserById(int id)
{
return usersRepository.GetByID(id);
}
public IEnumerable<UserModel> GetUsers()
{
return usersRepository.Get();
}
public long InsertUser(UserModel userModel)
{
var modelId = usersRepository.Insert(userModel);
this.UnitOfWork.Commit();
return modelId;
}
}
}
Addin UsersController
In Forms.WebPI project, we add the “UsersController.cs”:
using Forms.Managers.Interfaces;
using Forms.Models;
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
namespace Forms.WebAPI.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class UsersController : ControllerBase
{
private readonly IUsersManager usersManager;
public UsersController(IUsersManager usersManager)
{
this.usersManager = usersManager;
}
[HttpGet("{id}")]
public UserModel GetUserById(int id)
{
return usersManager.GetUserById(id);
}
[HttpGet]
public IEnumerable<UserModel> GetUsers()
{
return usersManager.GetUsers();
}
[HttpPost]
public long InserUser([FromBody] UserModel userModel)
{
return usersManager.InsertUser(userModel);
}
}
}
Dependency Injection:
In “startup.cs” class, we can tell “IOC” that we need the Database context, repositories and managers dependencies:
using Forms.DA;
using Forms.Managers;
using Forms.Managers.Interfaces;
using Forms.Repositories;
using Forms.Repositories.Commun;
using Forms.Repositories.Interfaces;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Swashbuckle.AspNetCore.Swagger;
namespace Forms.WebAPI
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddScoped<FormsContext>();
services.AddScoped<IUnitOfWork, UnitOfWork>();
services.AddScoped<IUsersManager, UsersManager>();
services.AddScoped<IUsersRepository, UsersRepository>();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseMvc();
}
}
}
Swagger:
As a reminder, Swagger offers tools to generate documentation for its Web API. It also provides an interface to explore and test the different methods offered by the service.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddScoped<FormsContext>();
services.AddScoped<IUnitOfWork, UnitOfWork>();
services.AddScoped<IUsersManager, UsersManager>();
services.AddScoped<IUsersRepository, UsersRepository>();
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new Info {Title = "Forms Api", Version = "V1" });
});
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseMvc();
app.UseSwagger();
app.UseSwaggerUI(s => s.SwaggerEndpoint("/swagger/v1/swagger.json", "Forms Api V1"));
}
All you need now, is to run the application in Visual Studio and navigate to “http://localhost:14957/swagger/index.html”. Make sure that you use the correct port in URL. In my case the port is “14957”.
Follow Me For Updates
Subscribe to my YouTube channel or follow me on Twitter or GitHub to be notified when I post new content.
[…] manipulate data structure like a C# or Java. So, we need to create the UserModel, like we did it in the last tutorial of Web API under the folder […]
Thiss is my first time pay a visit at here and i am truly impressed too read everthing at alone place.