منبع این مورد میزان مصرف حافظه، تجربیات شخصی بنده در کار با IE8 و همچنین فایرفاکس است.
+ Firefox Memory Hog را در گوگل جستجو کنید.
+ Firefox Memory Hog را در گوگل جستجو کنید.
using System.Collections.Generic; using System.Runtime.CompilerServices; namespace ConditionalWeakTableSamples { public static class AttachedProperties { public static ConditionalWeakTable<object, Dictionary<string, object>> ObjectCache = new ConditionalWeakTable<object, Dictionary<string, object>>(); public static void SetValue<T>(this T obj, string name, object value) where T : class { var properties = ObjectCache.GetOrCreateValue(obj); if (properties.ContainsKey(name)) properties[name] = value; else properties.Add(name, value); } public static T GetValue<T>(this object obj, string name) { Dictionary<string, object> properties; if (ObjectCache.TryGetValue(obj, out properties) && properties.ContainsKey(name)) return (T)properties[name]; return default(T); } public static object GetValue(this object obj, string name) { return obj.GetValue<object>(name); } } }
public static class ISecurityPrincipalExtension { public static bool Disclaimer(this IPrincipal principal) { return principal.GetValue<bool>("Disclaimer"); } public static void SetDisclaimer(this IPrincipal principal, bool value) { principal.SetValue("Disclaimer", value); } }
using System.Runtime.CompilerServices; namespace ConditionalWeakTableSamples { public static class PropertyExtensions { private class ExtraPropertyHolder { public bool IsDirty { get; set; } } private static readonly ConditionalWeakTable<object, ExtraPropertyHolder> _isDirtyTable = new ConditionalWeakTable<object, ExtraPropertyHolder>(); public static bool IsDirty(this object @this) { return _isDirtyTable.GetOrCreateValue(@this).IsDirty; } public static void SetIsDirty(this object @this, bool isDirty) { _isDirtyTable.GetOrCreateValue(@this).IsDirty = isDirty; } } }
public void Closed(DbConnection connection, DbConnectionInterceptionContext interceptionContext) { }
using System; using System.Runtime.CompilerServices; namespace ConditionalWeakTableSamples { public static class UniqueIdExtensions { static readonly ConditionalWeakTable<object, string> _idTable = new ConditionalWeakTable<object, string>(); public static string GetUniqueId(this object obj) { return _idTable.GetValue(obj, o => Guid.NewGuid().ToString()); } public static string GetUniqueId(this object obj, string key) { return _idTable.GetValue(obj, o => key); } } }
PM> Install-Package RazorGenerator.Mvc
PM> Enable-RazorGenerator
Copy "$(ProjectDir)$(OutDir)$(TargetName).*" "$(SolutionDir)MvcPluginMasterApp\bin\"
using System.Web.Mvc; namespace MvcPluginMasterApp.Plugin1.Areas.NewsArea { public class NewsAreaAreaRegistration : AreaRegistration { public override string AreaName { get { return "NewsArea"; } } public override void RegisterArea(AreaRegistrationContext context) { context.MapRoute( "NewsArea_default", "NewsArea/{controller}/{action}/{id}", // تکمیل نام کنترلر پیش فرض new { controller = "Home", action = "Index", id = UrlParameter.Optional }, // مشخص کردن فضای نام مرتبط جهت جلوگیری از تداخل با سایر قسمتهای برنامه namespaces: new[] { string.Format("{0}.Controllers", this.GetType().Namespace) } ); } } }
using System.Web.Mvc; using System.Web.Routing; namespace MvcPluginMasterApp { 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 }, // مشخص کردن فضای نام مرتبط جهت جلوگیری از تداخل با سایر قسمتهای برنامه namespaces: new[] { string.Format("{0}.Controllers", typeof(RouteConfig).Namespace) } ); } } }
using System; using System.Reflection; using System.Web.Optimization; using System.Web.Routing; using StructureMap; namespace MvcPluginMasterApp.PluginsBase { public interface IPlugin { EfBootstrapper GetEfBootstrapper(); MenuItem GetMenuItem(RequestContext requestContext); void RegisterBundles(BundleCollection bundles); void RegisterRoutes(RouteCollection routes); void RegisterServices(IContainer container); } public class EfBootstrapper { /// <summary> /// Assemblies containing EntityTypeConfiguration classes. /// </summary> public Assembly[] ConfigurationsAssemblies { get; set; } /// <summary> /// Domain classes. /// </summary> public Type[] DomainEntities { get; set; } /// <summary> /// Custom Seed method. /// </summary> //public Action<IUnitOfWork> DatabaseSeeder { get; set; } } public class MenuItem { public string Name { set; get; } public string Url { set; get; } } }
PM> install-package EntityFramework PM> install-package Microsoft.AspNet.Web.Optimization PM> install-package structuremap.web
using System.Web.Mvc; using System.Web.Optimization; using System.Web.Routing; using MvcPluginMasterApp.PluginsBase; using StructureMap; namespace MvcPluginMasterApp.Plugin1 { public class Plugin1 : IPlugin { public EfBootstrapper GetEfBootstrapper() { return null; } public MenuItem GetMenuItem(RequestContext requestContext) { return new MenuItem { Name = "Plugin 1", Url = new UrlHelper(requestContext).Action("Index", "Home", new { area = "NewsArea" }) }; } public void RegisterBundles(BundleCollection bundles) { //todo: ... } public void RegisterRoutes(RouteCollection routes) { //todo: add custom routes. } public void RegisterServices(IContainer container) { // todo: add custom services. container.Configure(cfg => { //cfg.For<INewsService>().Use<EfNewsService>(); }); } } }
using System; using System.IO; using System.Threading; using System.Web; using MvcPluginMasterApp.PluginsBase; using StructureMap; using StructureMap.Graph; namespace MvcPluginMasterApp.IoCConfig { public static class SmObjectFactory { private static readonly Lazy<Container> _containerBuilder = new Lazy<Container>(defaultContainer, LazyThreadSafetyMode.ExecutionAndPublication); public static IContainer Container { get { return _containerBuilder.Value; } } private static Container defaultContainer() { return new Container(cfg => { cfg.Scan(scanner => { scanner.AssembliesFromPath( path: Path.Combine(HttpRuntime.AppDomainAppPath, "bin"), // یک اسمبلی نباید دوبار بارگذاری شود assemblyFilter: assembly => { return !assembly.FullName.Equals(typeof(IPlugin).Assembly.FullName); }); scanner.WithDefaultConventions(); //Connects 'IName' interface to 'Name' class automatically. scanner.AddAllTypesOf<IPlugin>().NameBy(item => item.FullName); }); }); } } }
PM> install-package EntityFramework PM> install-package structuremap.web
using System.Linq; using System.Web.Optimization; using System.Web.Routing; using MvcPluginMasterApp; using MvcPluginMasterApp.IoCConfig; using MvcPluginMasterApp.PluginsBase; [assembly: WebActivatorEx.PostApplicationStartMethod(typeof(PluginsStart), "Start")] namespace MvcPluginMasterApp { public static class PluginsStart { public static void Start() { var plugins = SmObjectFactory.Container.GetAllInstances<IPlugin>().ToList(); foreach (var plugin in plugins) { plugin.RegisterServices(SmObjectFactory.Container); plugin.RegisterRoutes(RouteTable.Routes); plugin.RegisterBundles(BundleTable.Bundles); } } } }
@using MvcPluginMasterApp.IoCConfig @using MvcPluginMasterApp.PluginsBase @{ var plugins = SmObjectFactory.Container.GetAllInstances<IPlugin>().ToList(); } @foreach (var plugin in plugins) { var menuItem = plugin.GetMenuItem(this.Request.RequestContext); <li> <a href="@menuItem.Url">@menuItem.Name</a> </li> }
<div class="navbar navbar-inverse navbar-fixed-top"> <div class="container"> <div class="navbar-header"> <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> @Html.ActionLink("MvcPlugin Master App", "Index", "Home", new { area = "" }, new { @class = "navbar-brand" }) </div> <div class="navbar-collapse collapse"> <ul class="nav navbar-nav"> <li>@Html.ActionLink("Master App/Home", "Index", "Home", new {area = ""}, null)</li> @{ Html.RenderPartial("_PluginsMenu"); } </ul> </div> </div> </div>
using System;
using System.Collections.Generic;
namespace MvcApplication17.Models
{
public class Employee
{
public int Id { set; get; }
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime AddDate { get; set; }
public double Salary { get; set; }
public IList<Project> Projects { get; set; }
}
}
namespace MvcApplication17.Models
{
public class Project
{
public int Id { set; get; }
public string Name { set; get; }
}
}
using System;
using System.Collections.Generic;
namespace MvcApplication17.Models
{
public static class EmployeeDataSource
{
public static IList<Employee> CreateEmployees()
{
var list = new List<Employee>();
var rnd = new Random();
for (int i = 1; i <= 1000; i++)
{
list.Add(new Employee
{
Id = i + 1000,
FirstName = "fName " + i,
LastName = "lName " + i,
AddDate = DateTime.Now.AddYears(-rnd.Next(1, 10)),
Salary = rnd.Next(400, 3000),
Projects = CreateRandomProjects()
});
}
return list;
}
private static IList<Project> CreateRandomProjects()
{
var list = new List<Project>();
var rnd = new Random();
for (int i = 0; i < rnd.Next(1, 7); i++)
{
list.Add(new Project
{
Id = i,
Name = "Project " + i
});
}
return list;
}
}
}
using System.Web.Mvc;
using MvcApplication17.Models;
namespace MvcApplication17.Controllers
{
public class HomeController : Controller
{
[HttpPost]
public ActionResult Delete(int? id)
{
return RedirectToAction("Index");
}
[HttpGet]
public ActionResult Edit(int? id)
{
return View();
}
[HttpGet]
public ActionResult Index(string sort, string sortdir, int? page = 1)
{
var list = EmployeeDataSource.CreateEmployees();
return View(list);
}
}
}
http://localhost:3034/?sort=LastName&sortdir=ASC&page=3
@using System.Globalization
@model IList<MvcApplication17.Models.Employee>
@{
ViewBag.Title = "Index";
}
@helper WebGridPageFirstItem(WebGrid grid)
{
@(((grid.PageIndex + 1) * grid.RowsPerPage) - (grid.RowsPerPage - 1));
}
@helper WebGridPageLastItem(WebGrid grid)
{
if (grid.TotalRowCount < (grid.PageIndex + 1 * grid.RowsPerPage))
{
@grid.TotalRowCount;
}
else
{
@((grid.PageIndex + 1) * grid.RowsPerPage);
}
}
<h2>Employees List</h2>
@{
var grid = new WebGrid(
source: Model,
canPage: true,
rowsPerPage: 10,
canSort: true,
defaultSort: "FirstName"
);
var salaryPageSum = 0;
var taxPageSum = 0;
var rowIndex = ((grid.PageIndex + 1) * grid.RowsPerPage) - (grid.RowsPerPage - 1);
}
<div id="container">
@grid.GetHtml(
tableStyle: "webgrid",
headerStyle: "webgrid-header",
footerStyle: "webgrid-footer",
alternatingRowStyle: "webgrid-alternating-row",
selectedRowStyle: "webgrid-selected-row",
rowStyle: "webgrid-row-style",
htmlAttributes: new { id = "MyGrid" },
mode: WebGridPagerModes.All,
columns: grid.Columns(
grid.Column(header: "#",
style: "text-align-center-col",
format: @<text>@(rowIndex++)</text>),
grid.Column(columnName: "FirstName", header: "First Name",
format: @<span style='font-weight: bold'>@item.FirstName</span>,
style: "text-align-center-col"),
grid.Column(columnName: "LastName", header: "Last Name"),
grid.Column(header: "Image",
style: "text-align-center-col",
format: @<text><img alt="@item.Id" src="@Url.Content("~/images/" + @item.Id + ".jpg")" /></text>),
grid.Column(columnName: "AddDate", header: "Start",
style: "text-align-center-col",
format: item =>
{
int ym = item.AddDate.Year;
int mm = item.AddDate.Month;
int dm = item.AddDate.Day;
var persianCalendar = new PersianCalendar();
int ys = persianCalendar.GetYear(new DateTime(ym, mm, dm, new GregorianCalendar()));
int ms = persianCalendar.GetMonth(new DateTime(ym, mm, dm, new GregorianCalendar()));
int ds = persianCalendar.GetDayOfMonth(new DateTime(ym, mm, dm, new GregorianCalendar()));
return ys + "/" + ms.ToString("00") + "/" + ds.ToString("00");
}),
grid.Column(columnName: "Salary", header: "Salary",
format: item =>
{
salaryPageSum += item.Salary;
return string.Format("${0:n0}", item.Salary);
},
style: "text-align-center-col"),
grid.Column(header: "Tax", canSort: true,
format: item =>
{
var tax = item.Salary * 0.2;
taxPageSum += tax;
return string.Format("${0:n0}", tax);
}),
grid.Column(header: "Projects", columnName: "Projects",
style: "text-align-center-col",
format: item =>
{
var subGrid = new WebGrid(
source: item.Projects,
canPage: false,
canSort: false
);
return subGrid.GetHtml(
htmlAttributes: new { id = "MySubGrid" },
tableStyle: "webgrid",
headerStyle: "webgrid-header",
footerStyle: "webgrid-footer",
alternatingRowStyle: "webgrid-alternating-row",
selectedRowStyle: "webgrid-selected-row",
rowStyle: "webgrid-row-style"
);
}),
grid.Column(header: "",
style: "text-align-center-col",
format: item => @Html.ActionLink(linkText: "Edit", actionName: "Edit",
controllerName: "Home", routeValues: new { id = item.Id },
htmlAttributes: null)),
grid.Column(header: "",
format: @<form action="/Home/Delete/@item.Id" method="post"><input type="submit"
onclick="return confirm('Do you want to delete this record?');"
value="Delete"/></form>),
grid.Column(header: "", format: item => item.GetSelectLink("Select"))
)
)
<strong>Page:</strong> @(grid.PageIndex + 1) / @grid.PageCount,
<strong>Records:</strong> @WebGridPageFirstItem(@grid) - @WebGridPageLastItem(@grid) of @grid.TotalRowCount
@*
@if (@grid.HasSelection)
{
@RenderPage("~/views/path/_partial_view.cshtml", new { Employee = grid.SelectedRow })
}
*@
</div>
@section script{
<script type="text/javascript">
$(function () {
$('#MyGrid tbody:first').append(
'<tr class="total-row"><td></td>\
<td></td><td></td><td></td>\
<td><strong>Total:</strong></td>\
<td>@string.Format("${0:n0}", @salaryPageSum)</td>\
<td>@string.Format("${0:n0}", @taxPageSum)</td>\
<td></td><td></td><td></td></tr>');
});
</script>
}
@{
var grid = new WebGrid(
source: Model,
canPage: true,
rowsPerPage: 10,
canSort: true,
defaultSort: "FirstName"
);
var salaryPageSum = 0;
var taxPageSum = 0;
var rowIndex = ((grid.PageIndex + 1) * grid.RowsPerPage) - (grid.RowsPerPage - 1);
}
tableStyle: "webgrid",
headerStyle: "webgrid-header",
footerStyle: "webgrid-footer",
alternatingRowStyle: "webgrid-alternating-row",
selectedRowStyle: "webgrid-selected-row",
rowStyle: "webgrid-row-style",
htmlAttributes: new { id = "MyGrid" },
<div id="container">
<table class="webgrid" id="MyGrid">
<thead>
<tr class="webgrid-header">
/* Styles for WebGrid
-----------------------------------------------------------*/
.webgrid
{
width: 100%;
margin: 0px;
padding: 0px;
border: 0px;
border-collapse: collapse;
font-family: Tahoma;
font-size: 9pt;
}
.webgrid a
{
color: #000;
}
.webgrid-header
{
padding: 0px 5px;
text-align: center;
border-bottom: 2px solid #739ace;
height: 20px;
border-top: 2px solid #D6E8FF;
border-left: 2px solid #D6E8FF;
border-right: 2px solid #D6E8FF;
}
.webgrid-header th
{
background-color: #eaf0ff;
border-right: 1px solid #ddd;
}
.webgrid-footer
{
padding: 6px 5px;
text-align: center;
background-color: #e8eef4;
border-top: 2px solid #3966A2;
height: 25px;
border-bottom: 2px solid #D6E8FF;
border-left: 2px solid #D6E8FF;
border-right: 2px solid #D6E8FF;
}
.webgrid-alternating-row
{
height: 22px;
background-color: #f2f2f2;
border-bottom: 1px solid #d2d2d2;
border-left: 2px solid #D6E8FF;
border-right: 2px solid #D6E8FF;
}
.webgrid-row-style
{
height: 22px;
border-bottom: 1px solid #d2d2d2;
border-left: 2px solid #D6E8FF;
border-right: 2px solid #D6E8FF;
}
.webgrid-selected-row
{
font-weight: bold;
}
.text-align-center-col
{
text-align: center;
}
.total-row
{
background-color:#f9eef4;
}
[Flags]
public enum WebGridPagerModes
{
Numeric = 1,
//
NextPrevious = 2,
//
FirstLast = 4,
//
All = 7,
}
grid.Column(columnName: "FirstName", header: "First Name",
format: @<span style='font-weight: bold'>@item.FirstName</span>,
style: "text-align-center-col"),
grid.Column(columnName: "LastName", header: "Last Name"),
Func<dynamic, object> format
format: @<span style='font-weight: bold'>@item.FirstName</span>
or
format: item =>
{
salaryPageSum += item.Salary;
return string.Format("${0:n0}", item.Salary);
}
grid.Column(header: "#",
style: "text-align-center-col",
format: @<text>@(rowIndex++)</text>),
grid.Column(header: "Image",
style: "text-align-center-col",
format: @<text><img alt="@item.Id" src="@Url.Content("~/images/" + @item.Id + ".jpg")" /></text>),
grid.Column(columnName: "AddDate", header: "Start",
style: "text-align-center-col",
format: item =>
{
int ym = item.AddDate.Year;
int mm = item.AddDate.Month;
int dm = item.AddDate.Day;
var persianCalendar = new PersianCalendar();
int ys = persianCalendar.GetYear(new DateTime(ym, mm, dm, new GregorianCalendar()));
int ms = persianCalendar.GetMonth(new DateTime(ym, mm, dm, new GregorianCalendar()));
int ds = persianCalendar.GetDayOfMonth(new DateTime(ym, mm, dm, new GregorianCalendar()));
return ys + "/" + ms.ToString("00") + "/" + ds.ToString("00");
}),
grid.Column(columnName: "Salary", header: "Salary",
format: item =>
{
salaryPageSum += item.Salary;
return string.Format("${0:n0}", item.Salary);
},
style: "text-align-center-col"),
grid.Column(header: "Tax", canSort: true,
format: item =>
{
var tax = item.Salary * 0.2;
taxPageSum += tax;
return string.Format("${0:n0}", tax);
}),
grid.Column(header: "Projects", columnName: "Projects",
style: "text-align-center-col",
format: item =>
{
var subGrid = new WebGrid(
source: item.Projects,
canPage: false,
canSort: false
);
return subGrid.GetHtml(
htmlAttributes: new { id = "MySubGrid" },
tableStyle: "webgrid",
headerStyle: "webgrid-header",
footerStyle: "webgrid-footer",
alternatingRowStyle: "webgrid-alternating-row",
selectedRowStyle: "webgrid-selected-row",
rowStyle: "webgrid-row-style"
);
}),
grid.Column(header: "",
style: "text-align-center-col",
format: item => @Html.ActionLink(linkText: "Edit", actionName: "Edit",
controllerName: "Home", routeValues: new { id = item.Id },
htmlAttributes: null)),
grid.Column(header: "",
format: @<form action="/Home/Delete/@item.Id" method="post"><input type="submit"
onclick="return confirm('Do you want to delete this record?');"
value="Delete"/></form>),
grid.Column(header: "", format: item => item.GetSelectLink("Select"))
@if (@grid.HasSelection)
{
@RenderPage("~/views/path/_partial_view.cshtml", new { Employee = grid.SelectedRow })
}
<strong>Page:</strong> @(grid.PageIndex + 1) / @grid.PageCount,
<strong>Records:</strong> @WebGridPageFirstItem(@grid) - @WebGridPageLastItem(@grid) of @grid.TotalRowCount
@section script{
<script type="text/javascript">
$(function () {
$('#MyGrid tbody:first').append(
'<tr class="total-row"><td></td>\
<td></td><td></td><td></td>\
<td><strong>Total:</strong></td>\
<td>@string.Format("${0:n0}", @salaryPageSum)</td>\
<td>@string.Format("${0:n0}", @taxPageSum)</td>\
<td></td><td></td><td></td></tr>');
});
</script>
}
<head>
<title>@ViewBag.Title</title>
<link href="@Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />
<script src="@Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript"></script>
@RenderSection("script", required: false)
</head>