--HG--
branch : dev
This commit is contained in:
Sebastien Ros
2010-05-14 17:07:00 -07:00
16 changed files with 254 additions and 149 deletions

View File

@@ -0,0 +1,32 @@
using Autofac;
using NUnit.Framework;
using Orchard.Caching;
namespace Orchard.Tests.Caching {
[TestFixture]
public class CacheTests {
private IContainer _container;
private ICacheManager _cacheManager;
[SetUp]
public void Init() {
var builder = new ContainerBuilder();
builder.RegisterType<DefaultCacheManager>().As<ICacheManager>();
_container = builder.Build();
_cacheManager = _container.Resolve<ICacheManager>();
}
[Test]
public void CacheManagerShouldReturnCacheItem() {
var result = _cacheManager.Get("testItem", ctx => "testResult");
Assert.That(result, Is.EqualTo("testResult"));
}
[Test]
public void CacheManagerShouldReturnExistingCacheItem() {
_cacheManager.Get("testItem", ctx => "testResult");
var result = _cacheManager.Get("testItem", ctx => "");
Assert.That(result, Is.EqualTo("testResult"));
}
}
}

View File

@@ -117,6 +117,7 @@
</Reference> </Reference>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="Caching\CacheTests.cs" />
<Compile Include="Commands\CommandHandlerDescriptorBuilderTests.cs" /> <Compile Include="Commands\CommandHandlerDescriptorBuilderTests.cs" />
<Compile Include="Commands\CommandHandlerTests.cs" /> <Compile Include="Commands\CommandHandlerTests.cs" />
<Compile Include="Commands\CommandManagerTests.cs" /> <Compile Include="Commands\CommandManagerTests.cs" />

View File

@@ -44,44 +44,12 @@ namespace Orchard.Modules.Controllers {
}); });
} }
public ActionResult Features(FeaturesOptions options) { public ActionResult Features() {
if (!Services.Authorizer.Authorize(Permissions.ManageFeatures, T("Not allowed to manage features"))) if (!Services.Authorizer.Authorize(Permissions.ManageFeatures, T("Not allowed to manage features")))
return new HttpUnauthorizedResult(); return new HttpUnauthorizedResult();
var features = _moduleService.GetAvailableFeatures(); var features = _moduleService.GetAvailableFeatures();
return View(new FeaturesViewModel {Features = features, Options = options}); return View(new FeaturesViewModel {Features = features});
}
[HttpPost, ActionName("Features")]
[FormValueRequired("submit.BulkEdit")]
public ActionResult FeaturesPOST(FeaturesOptions options, IList<string> selection) {
if (selection != null && selection.Count > 0)
{
switch (options.BulkAction)
{
case FeaturesBulkAction.None:
break;
case FeaturesBulkAction.Enable:
if (!Services.Authorizer.Authorize(Permissions.ManageFeatures, T("Not allowed to enable features")))
return new HttpUnauthorizedResult();
_moduleService.EnableFeatures(selection);
//todo: (heskew) need better messages
//todo: (heskew) hmmm...need a helper to comma-separate all but last, which would get the " and " treatment...all localized, of course
Services.Notifier.Information(T("{0} were enabled", string.Join(", ", selection.ToArray())));
break;
case FeaturesBulkAction.Disable:
if (!Services.Authorizer.Authorize(Permissions.ManageFeatures, T("Not allowed to disable features")))
return new HttpUnauthorizedResult();
_moduleService.DisableFeatures(selection);
//todo: (heskew) need better messages
Services.Notifier.Information(T("{0} were disabled", string.Join(", ", selection.ToArray())));
break;
default:
throw new ArgumentOutOfRangeException();
}
}
return RedirectToAction("Features");
} }
[ValidateAntiForgeryTokenOrchard] [ValidateAntiForgeryTokenOrchard]
@@ -107,7 +75,7 @@ namespace Orchard.Modules.Controllers {
return new NotFoundResult(); return new NotFoundResult();
_moduleService.DisableFeatures(new[] { featureName }); _moduleService.DisableFeatures(new[] { featureName });
Services.Notifier.Information(T("{0} was disabled", featureName)); //Services.Notifier.Information(T("{0} was disabled", featureName));
return RedirectToAction("Features"); return RedirectToAction("Features");
} }

View File

@@ -48,10 +48,11 @@ namespace Orchard.Modules.Services {
} }
public IEnumerable<IModuleFeature> GetAvailableFeatures() { public IEnumerable<IModuleFeature> GetAvailableFeatures() {
var enabledFeatures = _shellDescriptorManager.GetShellDescriptor().EnabledFeatures; var enabledFeatures = _shellDescriptorManager.GetShellDescriptor().EnabledFeatures.ToList();
return GetInstalledModules() return GetInstalledModules()
.SelectMany(m => _extensionManager.LoadFeatures(m.Features)) .SelectMany(m => _extensionManager.LoadFeatures(m.Features))
.Select(f => AssembleModuleFromDescriptor(f, enabledFeatures.FirstOrDefault(sf => string.Equals(sf.Name, f.Descriptor.Name, StringComparison.OrdinalIgnoreCase)) != null)); .Select(f => AssembleModuleFromDescriptor(f, enabledFeatures.FirstOrDefault(sf => string.Equals(sf.Name, f.Descriptor.Name, StringComparison.OrdinalIgnoreCase)) != null))
.ToList();
} }
public IEnumerable<Feature> GetAvailableFeaturesByModule(string moduleName) { public IEnumerable<Feature> GetAvailableFeaturesByModule(string moduleName) {
@@ -69,9 +70,20 @@ namespace Orchard.Modules.Services {
public void DisableFeatures(IEnumerable<string> featureNames) { public void DisableFeatures(IEnumerable<string> featureNames) {
var shellDescriptor = _shellDescriptorManager.GetShellDescriptor(); var shellDescriptor = _shellDescriptorManager.GetShellDescriptor();
var enabledFeatures = shellDescriptor.EnabledFeatures.ToList(); var enabledFeatures = shellDescriptor.EnabledFeatures.ToList();
enabledFeatures.RemoveAll(f => featureNames.Contains(f.Name)); var features = GetAvailableFeatures();
foreach (var featureName in featureNames) {
var feature = featureName;
var dependants = features.Where(f => f.IsEnabled && f.Descriptor.Dependencies != null && f.Descriptor.Dependencies.Contains(feature));
if (dependants.Count() == 0) {
enabledFeatures.RemoveAll(f => f.Name == feature);
}
else {
// list what else will be disabled with ok/cancel
}
}
_shellDescriptorManager.UpdateShellDescriptor(shellDescriptor.SerialNumber, enabledFeatures, shellDescriptor.Parameters); _shellDescriptorManager.UpdateShellDescriptor(shellDescriptor.SerialNumber, enabledFeatures, shellDescriptor.Parameters);
} }

View File

@@ -4,16 +4,5 @@ using Orchard.Mvc.ViewModels;
namespace Orchard.Modules.ViewModels { namespace Orchard.Modules.ViewModels {
public class FeaturesViewModel : BaseViewModel { public class FeaturesViewModel : BaseViewModel {
public IEnumerable<IModuleFeature> Features { get; set; } public IEnumerable<IModuleFeature> Features { get; set; }
public FeaturesOptions Options { get; set; }
}
public class FeaturesOptions {
public FeaturesBulkAction BulkAction { get; set; }
}
public enum FeaturesBulkAction {
None,
Enable,
Disable
} }
} }

View File

@@ -2,62 +2,53 @@
<%@ Import Namespace="Orchard.Mvc.Html"%> <%@ Import Namespace="Orchard.Mvc.Html"%>
<%@ Import Namespace="Orchard.Modules.ViewModels"%> <%@ Import Namespace="Orchard.Modules.ViewModels"%>
<h1><%=Html.TitleForPage(T("Manage Features").ToString()) %></h1> <h1><%=Html.TitleForPage(T("Manage Features").ToString()) %></h1>
<div class="manage" style="visibility:hidden"><%=Html.ActionLink(T("∞").ToString(), "Features", new { }, new { @class = "button primaryAction" })%></div> <% if (Model.Features.Count() > 0) { %>
<% if (Model.Features.Count() > 0) { <ul class="contentItems"><%
var featureGroups = Model.Features.OrderBy(f => f.Descriptor.Category).GroupBy(f => f.Descriptor.Category);
using (Html.BeginFormAntiForgeryPost()) { %> foreach (var featureGroup in featureGroups) { %>
<%=Html.ValidationSummary()%> <li<%=featureGroup == featureGroups.Last() ? " class=\"last\"" : "" %>>
<fieldset class="actions bulk"> <h2><%=Html.Encode(featureGroup.First().Descriptor.Category ?? T("Uncategorized")) %></h2>
<label for="publishActions"><%=_Encoded("Actions: ")%></label> <ul><%
<select id="publishActions" name="<%=Html.NameOf(m => m.Options.BulkAction) %>"> var features = featureGroup.OrderBy(f => f.Descriptor.Name);
<%=Html.SelectOption(Model.Options.BulkAction, FeaturesBulkAction.None, _Encoded("Choose action...").ToString())%> foreach (var feature in features) {%>
<%=Html.SelectOption(Model.Options.BulkAction, FeaturesBulkAction.Enable, _Encoded("Enable").ToString())%> <li<%=feature == features.Last() ? " class=\"last\"" : "" %> id="<%=Html.Encode(feature.Descriptor.Name) %>">
<%=Html.SelectOption(Model.Options.BulkAction, FeaturesBulkAction.Disable, _Encoded("Disable").ToString())%> <div class="summary">
</select> <div class="properties">
<input class="button" type="submit" name="submit.BulkEdit" value="<%=_Encoded("Apply") %>" /> <h3><%=Html.Encode(feature.Descriptor.Name) %></h3>
</fieldset> <ul class="pageStatus">
<fieldset class="pageList"> <li><%
<ul class="contentItems"><% //enabled or not
foreach (var featureGroup in Model.Features.OrderBy(f => f.Descriptor.Category).GroupBy(f => f.Descriptor.Category)) { %> if (feature.IsEnabled) { %>
<li<%=featureGroup == Model.Features.Last() ? " class=\"last\"" : "" %>> <img class="icon" src="<%=ResolveUrl("~/Modules/Orchard.Modules/Content/Admin/images/enabled.gif") %>" alt="<%=_Encoded("Enabled") %>" title="<%=_Encoded("This feature is currently enabled") %>" /><%=_Encoded("Enabled") %><%
<h2><%=Html.Encode(featureGroup.First().Descriptor.Category ?? T("Uncategorized")) %></h2> }
<ul><% else { %>
foreach (var feature in featureGroup.OrderBy(f => f.Descriptor.Name)) {%> <img class="icon" src="<%=ResolveUrl("~/Modules/Orchard.Modules/Content/Admin/images/disabled.gif") %>" alt="<%=_Encoded("Disabled") %>" title="<%=_Encoded("This feature is currently disabled") %>" /><%=_Encoded("Disabled")%><%
<li<%=feature == featureGroup.Last() ? " class=\"last\"" : "" %> id="<%=Html.Encode(feature.Descriptor.Name) %>"> } %>
<div class="summary"> </li><%
<div class="properties"> //dependencies
<input type="checkbox" name="selection" value="<%=Html.Encode(feature.Descriptor.Name) %>" /> if (feature.Descriptor.Dependencies != null && feature.Descriptor.Dependencies.Count() > 0) { %>
<h3><%=Html.Encode(feature.Descriptor.Name) %></h3> <li>&nbsp;&#124;&nbsp;<%=T("Depends on: {0}", string.Join(", ", feature.Descriptor.Dependencies.Select(s => Html.Link(Html.Encode(s), string.Format("{0}#{1}", Url.Action("features", new { area = "Orchard.Modules" }), Html.Encode(s)))).OrderBy(s => s).ToArray())) %></li><%
<ul class="pageStatus"> } %>
<li><% </ul>
//enabled or not </div>
if (feature.IsEnabled) { %> <div class="related"><%
<img class="icon" src="<%=ResolveUrl("~/Modules/Orchard.Modules/Content/Admin/images/enabled.gif") %>" alt="<%=_Encoded("Enabled") %>" title="<%=_Encoded("This feature is currently enabled") %>" /><%=_Encoded("Enabled") %><% if (feature.IsEnabled) {
} using (Html.BeginFormAntiForgeryPost(string.Format("{0}#{1}", Url.Action("Disable", new { area = "Orchard.Modules" }), Html.AttributeEncode(feature.Descriptor.Name)), FormMethod.Post, new {@class = "inline link"})) { %>
else { %> <%=Html.Hidden("featureName", feature.Descriptor.Name) %>
<img class="icon" src="<%=ResolveUrl("~/Modules/Orchard.Modules/Content/Admin/images/disabled.gif") %>" alt="<%=_Encoded("Disabled") %>" title="<%=_Encoded("This feature is currently disabled") %>" /><%=_Encoded("Disabled")%><% <button type="submit"><%=_Encoded("Disable") %></button><%
} %> }
</li><% } else {
//dependencies using (Html.BeginFormAntiForgeryPost(string.Format("{0}#{1}", Url.Action("Enable", new { area = "Orchard.Modules" }), Html.AttributeEncode(feature.Descriptor.Name)), FormMethod.Post, new {@class = "inline link"})) { %>
if (feature.Descriptor.Dependencies != null && feature.Descriptor.Dependencies.Count() > 0) { %> <%=Html.Hidden("featureName", feature.Descriptor.Name) %>
<li>&nbsp;&#124;&nbsp;<%=T("Depends on: {0}", string.Join(", ", feature.Descriptor.Dependencies.Select(s => Html.Link(Html.Encode(s), string.Format("{0}#{1}", Url.Action("features", new { area = "Orchard.Modules" }), Html.Encode(s)))).OrderBy(s => s).ToArray())) %></li><% <button type="submit"><%=_Encoded("Enable") %></button><%
} %> }
</ul> } %>
</div> </div>
<div class="related"><% </div>
if (feature.IsEnabled) { %>
<a href="<%=Html.AntiForgeryTokenGetUrl(Url.Action("Disable", new { featureName = feature.Descriptor.Name, area = "Orchard.Modules" })) %>"><%=_Encoded("Disable") %></a><%
} else { %>
<a href="<%=Html.AntiForgeryTokenGetUrl(Url.Action("Enable", new { featureName = feature.Descriptor.Name, area = "Orchard.Modules" })) %>"><%=_Encoded("Enable") %></a><%
} %>
</div>
</div>
</li><%
} %>
</ul>
</li><% </li><%
} %> } %>
</ul><% </ul>
} %> </li><%
</fieldset><% } %>
</ul><%
} %> } %>

View File

@@ -50,10 +50,10 @@ jQuery.fn.extend({
(function() { (function() {
$("form.inline.link").each(function() { $("form.inline.link").each(function() {
var _this = $(this); var _this = $(this);
var link = $("<a href='.'/>"); var link = $("<a class='wasFormInlineLink' href='.'/>");
var button = _this.children("button").first(); var button = _this.children("button").first();
link.text(button.text()) link.text(button.text())
.css("cursor", "pointer") .addClass(button.attr("class"))
.click(function() { _this.submit(); return false; }) .click(function() { _this.submit(); return false; })
.unload(function() { _this = 0; }); .unload(function() { _this = 0; });
_this.replaceWith(link); _this.replaceWith(link);

View File

@@ -27,33 +27,24 @@
<div> <div>
<h3><%=Html.Encode(theme.DisplayName) %></h3> <h3><%=Html.Encode(theme.DisplayName) %></h3>
<%=Html.Image(Html.ThemePath(theme, "/Theme.png"), Html.Encode(theme.DisplayName), null)%> <%=Html.Image(Html.ThemePath(theme, "/Theme.png"), Html.Encode(theme.DisplayName), null)%>
<% using (Html.BeginFormAntiForgeryPost(Url.Action("Activate"), FormMethod.Post, new { @class = "inline" })) { %>
<% using (Html.BeginFormAntiForgeryPost(Url.Action("Activate"), FormMethod.Post, new { @class = "inline" })) <%=Html.Hidden("themeName", theme.ThemeName)%>
{ %> <button type="submit" title="<%=_Encoded("Activate") %>"><%=_Encoded("Activate") %></button>
<fieldset> <% } %>
<button type="submit" title="<%=_Encoded("Activate") %>" name="themeName" value="<%=theme.ThemeName %>"><%=_Encoded("Activate") %></button> <% using (Html.BeginFormAntiForgeryPost(Url.Action("Preview"), FormMethod.Post, new { @class = "inline" })) { %>
</fieldset> <%=Html.Hidden("themeName", theme.ThemeName)%>
<% } %> <button type="submit" title="<%=_Encoded("Preview") %>"><%=_Encoded("Preview") %></button>
<% using (Html.BeginFormAntiForgeryPost(Url.Action("Preview"), FormMethod.Post, new { @class = "inline" })) <% } %>
{ %>
<fieldset>
<button type="submit" title="<%=_Encoded("Preview") %>" name="themeName" value="<%=theme.ThemeName %>"><%=_Encoded("Preview") %></button>
</fieldset>
<% } %>
<h5><%=_Encoded("By") %> <%=Html.Encode(theme.Author) %></h5> <h5><%=_Encoded("By") %> <%=Html.Encode(theme.Author) %></h5>
<p> <p>
<%=_Encoded("Version:") %> <%=Html.Encode(theme.Version) %><br /> <%=_Encoded("Version:") %> <%=Html.Encode(theme.Version) %><br />
<%=Html.Encode(theme.Description) %><br /> <%=Html.Encode(theme.Description) %><br />
<%=Html.Encode(theme.HomePage) %> <%=Html.Encode(theme.HomePage) %>
</p> </p>
<% using (Html.BeginFormAntiForgeryPost(Url.Action("Uninstall"), FormMethod.Post, new { @class = "inline" })) <% using (Html.BeginFormAntiForgeryPost(Url.Action("Uninstall"), FormMethod.Post, new { @class = "inline link" })) { %>
{ %> <%=Html.Hidden("themeName", theme.ThemeName)%>
<fieldset> <button type="submit" class="uninstall" title="<%=_Encoded("Uninstall") %>"><%=_Encoded("Uninstall")%></button>
<button type="submit" class="linkButton" title="<%=_Encoded("Uninstall") %>" name="themeName" value="<%=theme.ThemeName %>"><%=_Encoded("Uninstall")%></button> <% } %>
</fieldset>
<% } %>
</div> </div>
</li> </li>
<% } <% }

View File

@@ -2,37 +2,68 @@
<%@ Import Namespace="Orchard.Mvc.Html"%> <%@ Import Namespace="Orchard.Mvc.Html"%>
<%@ Import Namespace="Orchard.Themes.ViewModels"%> <%@ Import Namespace="Orchard.Themes.ViewModels"%>
<style type="text/css"> <style type="text/css">
#themepreview, #themepreview fieldset, #themepreview input, #themepreview select body {
{ margin-top:40px;
margin: 0; padding: 0; border:none; font-size: 1em; width:auto; color: #000;
font-family:Frutiger,"Frutiger Linotype",Univers,Calibri,"Gill Sans","Gill Sans MT","Myriad Pro",Myriad,"DejaVu Sans Condensed","Liberation Sans","Nimbus Sans L",Tahoma,Geneva,"Helvetica Neue",Helvetica,Arial,sans-serif;
} }
/*#themepreview { background: #000; font-size:15px; padding:5px; }*/ #themepreview {
#themepreview span { color: #ccc; padding-right:5px; } background:#2D2F25 url('<%=ResolveUrl("../../Styles/Images/toolBarBackground.gif") %>') repeat-x left top;
#themepreview fieldset { margin: 0; padding: 3px; } border-bottom:1px solid #494d4d;
/*#themepreview button { font-size: 13px; padding:0 3px; margin-left:10px; }*/ font-size:15px;
#themepreview button.preview { margin-left:0; } left:0;
height:30px;
margin:0;
position:absolute;
overflow:hidden;
padding:5px 0;
top:0;
width:100%;
}
#themepreview fieldset,
#themepreview span, #themepreview input,
#themepreview select, #themepreview button {
border:none;
color:#000;
font:1em/1em Frutiger,"Frutiger Linotype",Univers,Calibri,"Gill Sans","Gill Sans MT","Myriad Pro",Myriad,"DejaVu Sans Condensed","Liberation Sans","Nimbus Sans L",Tahoma,Geneva,"Helvetica Neue",Helvetica,Arial,sans-serif;
margin:0;
padding:0;
width:auto;
}
#themepreview span { color: #ccc; padding-right:5px; }
#themepreview fieldset { padding:3px 8px; }
html.dyn #themepreview button.preview { display:none; } html.dyn #themepreview button.preview { display:none; }
#themepreview fieldset * { float:left; }
#themepreview fieldset span { line-height:1.6em; }
#themepreview button.cancel { float:right; } #themepreview button.cancel { float:right; }
#themepreview { background: #2D2F25 url('<%=ResolveUrl("../../Styles/Images/toolBarBackground.gif") %>') repeat-x left top; font-size:15px; padding:5px; border-bottom:1px solid #494d4d;}
/* Button styles */ /* Button styles */
#themepreview button { font-size: 13px; padding:2px 4px; margin: 0 0 0 10px; text-align:center; color:#f1f1f1; border:1px solid; border-top-color:#191d1d; border-right-color:#494d4d; border-bottom-color:#494d4d; border-left-color:#202626; background:#2a2626 url('<%=ResolveUrl("../../Styles/Images/toolBarActiveButtonBackground.gif") %>') repeat-x left center; } #themepreview button {
background:#2a2626 url('<%=ResolveUrl("../../Styles/Images/toolBarActiveButtonBackground.gif") %>') repeat-x left center;
/* Hover for buttons */ border:1px solid;
#themepreview button:hover { color:#fdcc64; border:1px #545959 solid; cursor:pointer; background:#2a2626 url('<%=ResolveUrl("../../Styles/Images/toolBarHoverButtonBackground.gif") %>') repeat-x left center; } border-top-color:#191d1d;
border-right-color:#494d4d;
border-bottom-color:#494d4d;
border-left-color:#202626;
color:#f1f1f1;
line-height:1.22em;
margin: 0 0 0 10px;
padding:0 4px 1px;
text-align:center;
}
#themepreview button:hover {
background:#2a2626 url('<%=ResolveUrl("../../Styles/Images/toolBarHoverButtonBackground.gif") %>') repeat-x left center;
border-color:#545959;
color:#fdcc64;
cursor:pointer;
}
</style> </style>
<div id="themepreview"> <div id="themepreview">
<% using(Html.BeginFormAntiForgeryPost(Url.Action("Preview", new{Controller="Admin", Area="Orchard.Themes"}), FormMethod.Post, new { @class = "inline" })) { %> <% using(Html.BeginFormAntiForgeryPost(Url.Action("Preview", new{Controller="Admin", Area="Orchard.Themes"}), FormMethod.Post, new { @class = "inline" })) { %>
<fieldset> <fieldset>
<span><%=T("You are previewing: ")%></span> <span><%=T("You are previewing: ")%></span>
<%=Html.Hidden("ReturnUrl", Context.Request.Url)%>
<%=Html.DropDownList("ThemeName", Model.Themes, new {onChange = "this.form.submit();"})%> <%=Html.DropDownList("ThemeName", Model.Themes, new {onChange = "this.form.submit();"})%>
<button type="submit" class="preview" title="<%=_Encoded("Preview")%>" name="submit.Preview" value="<%=_Encoded("Preview")%>"><%=_Encoded("Preview")%></button> <button type="submit" class="preview" title="<%=_Encoded("Preview")%>" name="submit.Preview" value="<%=_Encoded("Preview")%>"><%=_Encoded("Preview")%></button>
<button type="submit" title="<%=_Encoded("Apply")%>" name="submit.Apply" value="<%=_Encoded("Apply")%>"><%=_Encoded("Apply this theme") %></button> <button type="submit" title="<%=_Encoded("Apply")%>" name="submit.Apply" value="<%=_Encoded("Apply")%>"><%=_Encoded("Apply this theme") %></button>
<button type="submit" class="cancel" title="<%=_Encoded("Cancel")%>" name="submit.Cancel" value="<%=_Encoded("Cancel")%>"><%=_Encoded("Cancel")%></button> <button type="submit" class="cancel" title="<%=_Encoded("Cancel")%>" name="submit.Cancel" value="<%=_Encoded("Cancel")%>"><%=_Encoded("Cancel")%></button>
<%=Html.Hidden("ReturnUrl", Context.Request.Url)%>
</fieldset> </fieldset>
<% } %> <% } %>
</div> </div>

View File

@@ -731,8 +731,11 @@ todo: (heskew) pull out into relevant modules where appropriate
zoom:1; zoom:1;
*display: inline; *display: inline;
} }
.templates fieldset { .templates .inline button {
margin:0 0 .933%; font-size:1.2em;
}
.templates .wasFormInlineLink {
font-size:1.4em;
} }
.templates p { .templates p {
overflow:hidden; overflow:hidden;

View File

@@ -0,0 +1,4 @@
namespace Orchard.Caching {
public class AcquireContext {
}
}

View File

@@ -0,0 +1,31 @@
using System;
using System.Collections.Generic;
namespace Orchard.Caching {
public class Cache<TKey, TResult> : ICache<TKey, TResult> {
private readonly Dictionary<TKey, CacheEntry> _entries;
public Cache() {
_entries = new Dictionary<TKey, CacheEntry>();
}
#region Implementation of ICache<TKey,TResult>
public TResult Get(TKey key, Func<AcquireContext, TResult> acquire) {
CacheEntry entry;
if (!_entries.TryGetValue(key, out entry)) {
AcquireContext context = new AcquireContext();
entry = new CacheEntry {Result = acquire(context)};
_entries.Add(key, entry);
}
return entry.Result;
}
#endregion
public class CacheEntry {
public TResult Result { get; set; }
}
}
}

View File

@@ -0,0 +1,32 @@
using System;
using System.Collections.Generic;
using Castle.Core;
namespace Orchard.Caching {
public class DefaultCacheManager : ICacheManager {
private readonly Dictionary<Pair<Type, Type>, object> _caches;
public DefaultCacheManager() {
_caches = new Dictionary<Pair<Type, Type>, object>();
}
#region Implementation of ICacheManager
public TResult Get<TKey, TResult>(TKey key, Func<AcquireContext, TResult> acquire) {
return GetCache<TKey, TResult>().Get(key, acquire);
}
public ICache<TKey, TResult> GetCache<TKey, TResult>() {
var cacheKey = new Pair<Type, Type>(typeof(TKey), typeof(TResult));
object value;
if (!_caches.TryGetValue(cacheKey, out value)) {
value = new Cache<TKey, TResult>();
_caches.Add(cacheKey, value);
}
return (ICache<TKey, TResult>)value;
}
#endregion
}
}

View File

@@ -0,0 +1,7 @@
using System;
namespace Orchard.Caching {
public interface ICache<TKey, TResult> {
TResult Get(TKey key, Func<AcquireContext, TResult> acquire);
}
}

View File

@@ -0,0 +1,8 @@
using System;
namespace Orchard.Caching {
public interface ICacheManager : ISingletonDependency {
TResult Get<TKey, TResult>(TKey key, Func<AcquireContext, TResult> acquire);
ICache<TKey, TResult> GetCache<TKey, TResult>();
}
}

View File

@@ -131,6 +131,11 @@
<Compile Include="Validation\Argument.cs" /> <Compile Include="Validation\Argument.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="Caching\AcquireContext.cs" />
<Compile Include="Caching\Cache.cs" />
<Compile Include="Caching\DefaultCacheManager.cs" />
<Compile Include="Caching\ICache.cs" />
<Compile Include="Caching\ICacheManager.cs" />
<Compile Include="Commands\CommandParameters.cs" /> <Compile Include="Commands\CommandParameters.cs" />
<Compile Include="Commands\CommandDescriptor.cs" /> <Compile Include="Commands\CommandDescriptor.cs" />
<Compile Include="Commands\CommandHandlerDescriptor.cs" /> <Compile Include="Commands\CommandHandlerDescriptor.cs" />