Suggested Videos
Part 4 - Thread Safety in Singleton - Text - Slides
Part 5 - Lazy vs Eager loading in Singleton - Text - Slides
Part 6 - Static Class vs Singleton - Text - Slides
(追記) (追記ここまで)
In this tutorial we will discuss how to create a simple employee web application using ASP.NET MVC and we will create a custom logger library using Singleton design pattern which logs exceptions to an external file
(追記) (追記ここまで)
Logger Library
Part 4 - Thread Safety in Singleton - Text - Slides
Part 5 - Lazy vs Eager loading in Singleton - Text - Slides
Part 6 - Static Class vs Singleton - Text - Slides
(追記) (追記ここまで)
In this tutorial we will discuss how to create a simple employee web application using ASP.NET MVC and we will create a custom logger library using Singleton design pattern which logs exceptions to an external file
(追記) (追記ここまで)
Logger Library
ILog.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Logger
{
publicinterfaceILog
{
void LogException(string message);
}
}
Log.cs
using System;
using
System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Logger
{
publicsealedclassLog : ILog
{
private Log()
{
}
privatestaticreadonlyLazy<Log> instance =
newLazy<Log>(() => newLog());
publicstaticLog GetInstance
{
get
{
return
instance.Value;
}
}
publicvoid LogException(string message)
{
string fileName = string.Format("{0}_{1}.log", "Exception", DateTime.Now.ToShortDateString());
string logFilePath = string.Format(@"{0}\{1}", AppDomain.CurrentDomain.BaseDirectory, fileName);
StringBuilder sb = newStringBuilder();
sb.AppendLine("----------------------------------------");
sb.AppendLine(DateTime.Now.ToString());
sb.AppendLine(message);
using (StreamWriter writer =
newStreamWriter(logFilePath,
true))
{
writer.Write(sb.ToString());
writer.Flush();
}
}
}
}
Create and MVC
Application and Create EmployeePortal DB with Employee Table
Employee Table
CREATETABLE [dbo].[Employee](
[Id] INTIDENTITY (1, 1)NOTNULL,
[Name] VARCHAR (50)NOTNULL,
[JobDescription] VARCHAR (50)NOTNULL,
[Number] VARCHAR (50)NOTNULL,
[Department] VARCHAR (50)NOTNULL,
PRIMARYKEYCLUSTERED ([Id] ASC)
);
Generate Model using
ADO.Net entity model generator using the above Table. Post generation, Add an
Employee controller and use generated model which further creates views for
Employee which facilitates CRUD operations on the employee.
Sample EmployeeController.cs
using Logger;
using System;
using
System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Mvc;
using Web.Models;
namespace Web.Controllers
{
publicclassEmployeesController : Controller
{
privateILog _ILog;
privateEmployeePortalEntities db = newEmployeePortalEntities();
public
EmployeesController()
{
_ILog = Log.GetInstance;
}
protectedoverridevoid OnException(ExceptionContext filterContext)
{
_ILog.LogException(filterContext.Exception.ToString());
filterContext.ExceptionHandled = true;
this.View("Error").ExecuteResult(this.ControllerContext);
}
// GET: Employees
publicActionResult Index()
{
return
View(db.Employees.ToList());
}
// GET: Employees/Details/5
publicActionResult Details(int? id)
{
if (id == null)
{
returnnewHttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Employee employee =
db.Employees.Find(id);
if (employee == null)
{
return
HttpNotFound();
}
return
View(employee);
}
// GET: Employees/Create
publicActionResult Create()
{
return View();
}
// POST: Employees/Create
// To protect from overposting attacks, please enable the
specific properties you want to bind to, for
// more details see
http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
publicActionResult Create([Bind(Include = "Id,Name,JobDescription,Number,Department")] Employee employee)
{
if
(ModelState.IsValid)
{
db.Employees.Add(employee);
db.SaveChanges();
return
RedirectToAction("Index");
}
return
View(employee);
}
// GET: Employees/Edit/5
publicActionResult Edit(int? id)
{
if (id == null)
{
returnnewHttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Employee employee =
db.Employees.Find(id);
if (employee == null)
{
return
HttpNotFound();
}
return
View(employee);
}
// POST: Employees/Edit/5
// To
protect from overposting attacks, please enable the specific properties you
want to bind to, for
// more details see
http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
publicActionResult Edit([Bind(Include = "Id,Name,JobDescription,Number,Department")] Employee employee)
{
if
(ModelState.IsValid)
{
db.Entry(employee).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return
View(employee);
}
// GET: Employees/Delete/5
publicActionResult Delete(int? id)
{
if (id == null)
{
returnnewHttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Employee employee =
db.Employees.Find(id);
if (employee == null)
{
return
HttpNotFound();
}
return View(employee);
}
// POST: Employees/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
publicActionResult
DeleteConfirmed(int id)
{
Employee employee =
db.Employees.Find(id);
db.Employees.Remove(employee);
db.SaveChanges();
return
RedirectToAction("Index");
}
protectedoverridevoid Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
}
}
}
- Run the application and all the exceptions will be logged under the file created by the logger class library.
- This Proves that singleton design pattern comes handy in the situations where we need to have a single instance of the object.
- Now, to consider another example, we can design Cache Management to use and leverage on Singleton design pattern as we can handle reads and writes to external caches using the Single Cache instance object.
2 comments:
Thanks for explaining singleton, but what will be the advantage of using singleton over static class for log class, please explain. I remember using a logger third part tool which exposes static class implementation. Please explain if I got the concept wrong.
Reply Delete@rajiv, A static class cannot implement an interface. And in this example we have implemented an interface
DeleteIt would be great if you can help share these free resources
[フレーム]