diff --git a/Orchard.proj b/Orchard.proj index a68d2afa3..b907eb655 100644 --- a/Orchard.proj +++ b/Orchard.proj @@ -69,7 +69,7 @@ - + @@ -126,7 +126,7 @@ - + @@ -293,10 +293,18 @@ + + - + + + + + @@ -307,7 +315,6 @@ - diff --git a/src/Orchard.Core.Tests/Routable/Services/RoutableServiceTests.cs b/src/Orchard.Core.Tests/Routable/Services/RoutableServiceTests.cs index 62493aaab..c696c8b75 100644 --- a/src/Orchard.Core.Tests/Routable/Services/RoutableServiceTests.cs +++ b/src/Orchard.Core.Tests/Routable/Services/RoutableServiceTests.cs @@ -46,7 +46,7 @@ namespace Orchard.Core.Tests.Routable.Services { builder.RegisterInstance(new Mock().Object); builder.RegisterInstance(new Mock().Object); builder.RegisterType().As(); - builder.RegisterType().As(); + builder.RegisterType().As(); builder.RegisterType().As(); builder.RegisterType().As(); diff --git a/src/Orchard.Profile/Tests/Profiling.feature b/src/Orchard.Profile/Tests/Profiling.feature index 267b90d37..cadf674cb 100644 --- a/src/Orchard.Profile/Tests/Profiling.feature +++ b/src/Orchard.Profile/Tests/Profiling.feature @@ -22,5 +22,8 @@ Scenario: Hitting blogs When I go to "/blog4" 10 times Scenario: Hitting home page - Given I am logged in - When I go to "/" 40 times + //Given I am logged in + When I go to "/" 10 times + When I go to "/" 10 times + When I go to "/" 10 times + When I go to "/" 10 times diff --git a/src/Orchard.Profile/Tests/Profiling.feature.cs b/src/Orchard.Profile/Tests/Profiling.feature.cs index ae57373ee..75bb2fb49 100644 --- a/src/Orchard.Profile/Tests/Profiling.feature.cs +++ b/src/Orchard.Profile/Tests/Profiling.feature.cs @@ -1,7 +1,7 @@ // ------------------------------------------------------------------------------ // // This code was generated by SpecFlow (http://www.specflow.org/). -// SpecFlow Version:1.3.2.0 +// SpecFlow Version:1.4.0.0 // Runtime Version:4.0.30319.1 // // Changes to this file may cause incorrect behavior and will be lost if @@ -9,12 +9,12 @@ // // ------------------------------------------------------------------------------ #region Designer generated code -namespace Orchard.Specs.Le.Tests +namespace Orchard.Profile.Tests { using TechTalk.SpecFlow; - [System.CodeDom.Compiler.GeneratedCodeAttribute("TechTalk.SpecFlow", "1.3.2.0")] + [System.CodeDom.Compiler.GeneratedCodeAttribute("TechTalk.SpecFlow", "1.4.0.0")] [System.Runtime.CompilerServices.CompilerGeneratedAttribute()] [NUnit.Framework.TestFixtureAttribute()] [NUnit.Framework.DescriptionAttribute("Profiling")] @@ -31,7 +31,7 @@ namespace Orchard.Specs.Le.Tests { testRunner = TechTalk.SpecFlow.TestRunnerManager.GetTestRunner(); TechTalk.SpecFlow.FeatureInfo featureInfo = new TechTalk.SpecFlow.FeatureInfo(new System.Globalization.CultureInfo("en-US"), "Profiling", "In order to profile the site\r\nAs a developer\r\nI want to generate a fixed number o" + - "f repeatable requests", ((string[])(null))); + "f repeatable requests", GenerationTargetLanguage.CSharp, ((string[])(null))); testRunner.OnFeatureStart(featureInfo); } @@ -61,13 +61,13 @@ namespace Orchard.Specs.Le.Tests #line 6 this.ScenarioSetup(scenarioInfo); #line 7 -testRunner.Given("I am logged in"); + testRunner.Given("I am logged in"); #line 8 -testRunner.When("I go to \"/admin\""); + testRunner.When("I go to \"/admin\""); #line 9 -testRunner.When("I go to \"/blog0\""); + testRunner.When("I go to \"/blog0\""); #line 10 -testRunner.When("I go to \"/\""); + testRunner.When("I go to \"/\""); #line hidden testRunner.CollectScenarioErrors(); } @@ -80,9 +80,9 @@ testRunner.When("I go to \"/\""); #line 12 this.ScenarioSetup(scenarioInfo); #line 13 -testRunner.Given("I am logged in"); + testRunner.Given("I am logged in"); #line 14 -testRunner.When("I go to \"/admin\" 40 times"); + testRunner.When("I go to \"/admin\" 40 times"); #line hidden testRunner.CollectScenarioErrors(); } @@ -95,17 +95,17 @@ testRunner.When("I go to \"/admin\" 40 times"); #line 16 this.ScenarioSetup(scenarioInfo); #line 17 -testRunner.Given("I am logged in"); + testRunner.Given("I am logged in"); #line 18 -testRunner.When("I go to \"/blog0\" 10 times"); + testRunner.When("I go to \"/blog0\" 10 times"); #line 19 -testRunner.When("I go to \"/blog1\" 10 times"); + testRunner.When("I go to \"/blog1\" 10 times"); #line 20 -testRunner.When("I go to \"/blog2\" 10 times"); + testRunner.When("I go to \"/blog2\" 10 times"); #line 21 -testRunner.When("I go to \"/blog3\" 10 times"); + testRunner.When("I go to \"/blog3\" 10 times"); #line 22 -testRunner.When("I go to \"/blog4\" 10 times"); + testRunner.When("I go to \"/blog4\" 10 times"); #line hidden testRunner.CollectScenarioErrors(); } @@ -117,10 +117,14 @@ testRunner.When("I go to \"/blog4\" 10 times"); TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Hitting home page", ((string[])(null))); #line 24 this.ScenarioSetup(scenarioInfo); -#line 25 -testRunner.Given("I am logged in"); #line 26 -testRunner.When("I go to \"/\" 40 times"); + testRunner.When("I go to \"/\" 10 times"); +#line 27 + testRunner.When("I go to \"/\" 10 times"); +#line 28 + testRunner.When("I go to \"/\" 10 times"); +#line 29 + testRunner.When("I go to \"/\" 10 times"); #line hidden testRunner.CollectScenarioErrors(); } diff --git a/src/Orchard.Tests/Environment/DefaultWorkContextAccessorTests.cs b/src/Orchard.Tests/Environment/DefaultWorkContextAccessorTests.cs index 8edd2de91..5de77cf97 100644 --- a/src/Orchard.Tests/Environment/DefaultWorkContextAccessorTests.cs +++ b/src/Orchard.Tests/Environment/DefaultWorkContextAccessorTests.cs @@ -22,7 +22,7 @@ namespace Orchard.Tests.Environment { } protected override void Register(ContainerBuilder builder) { - builder.RegisterType().As(); + builder.RegisterType().As(); builder.RegisterAutoMocking(); } diff --git a/src/Orchard.Tests/Environment/ShellBuilders/DefaultShellContextFactoryTests.cs b/src/Orchard.Tests/Environment/ShellBuilders/DefaultShellContextFactoryTests.cs index 56a96df61..4857f4b72 100644 --- a/src/Orchard.Tests/Environment/ShellBuilders/DefaultShellContextFactoryTests.cs +++ b/src/Orchard.Tests/Environment/ShellBuilders/DefaultShellContextFactoryTests.cs @@ -21,7 +21,7 @@ namespace Orchard.Tests.Environment.ShellBuilders { public void Init() { var builder = new ContainerBuilder(); builder.RegisterType().As(); - builder.RegisterType().As(); + builder.RegisterType().As(); builder.RegisterAutoMocking(Moq.MockBehavior.Strict); _container = builder.Build(); } diff --git a/src/Orchard.Tests/Environment/State/DefaultProcessingEngineTests.cs b/src/Orchard.Tests/Environment/State/DefaultProcessingEngineTests.cs index e35a2f401..d564bb24c 100644 --- a/src/Orchard.Tests/Environment/State/DefaultProcessingEngineTests.cs +++ b/src/Orchard.Tests/Environment/State/DefaultProcessingEngineTests.cs @@ -23,7 +23,7 @@ namespace Orchard.Tests.Environment.State { public void Init() { var builder = new ContainerBuilder(); builder.RegisterType().As(); - builder.RegisterType().As(); + builder.RegisterType().As(); builder.RegisterAutoMocking(); _container = builder.Build(); diff --git a/src/Orchard.Tests/Localization/CultureManagerTests.cs b/src/Orchard.Tests/Localization/CultureManagerTests.cs index 9d202c2d0..4a0d9e1ce 100644 --- a/src/Orchard.Tests/Localization/CultureManagerTests.cs +++ b/src/Orchard.Tests/Localization/CultureManagerTests.cs @@ -51,7 +51,7 @@ namespace Orchard.Tests.Localization { builder.RegisterInstance(new Mock().Object); builder.RegisterInstance(new Mock().Object); builder.RegisterType().As(); - builder.RegisterType().As(); + builder.RegisterType().As(); builder.RegisterType().As(); builder.RegisterType().As(); builder.RegisterType().As(); diff --git a/src/Orchard.Tests/Mvc/Routes/ShellRouteTests.cs b/src/Orchard.Tests/Mvc/Routes/ShellRouteTests.cs index 80a99f72f..33bbfb968 100644 --- a/src/Orchard.Tests/Mvc/Routes/ShellRouteTests.cs +++ b/src/Orchard.Tests/Mvc/Routes/ShellRouteTests.cs @@ -36,7 +36,7 @@ namespace Orchard.Tests.Mvc.Routes { rootBuilder.Register(ctx => _routes); rootBuilder.RegisterType().InstancePerDependency(); rootBuilder.RegisterType().As().SingleInstance(); - rootBuilder.RegisterType().As().InstancePerMatchingLifetimeScope("shell"); + rootBuilder.RegisterType().As().InstancePerMatchingLifetimeScope("shell"); rootBuilder.RegisterType().As(); _rootContainer = rootBuilder.Build(); diff --git a/src/Orchard.Tests/Tasks/SweepGeneratorTests.cs b/src/Orchard.Tests/Tasks/SweepGeneratorTests.cs index 9e0469631..9bb99fa08 100644 --- a/src/Orchard.Tests/Tasks/SweepGeneratorTests.cs +++ b/src/Orchard.Tests/Tasks/SweepGeneratorTests.cs @@ -12,7 +12,7 @@ namespace Orchard.Tests.Tasks { public class SweepGeneratorTests : ContainerTestBase { protected override void Register(ContainerBuilder builder) { builder.RegisterAutoMocking(MockBehavior.Loose); - builder.RegisterType().As(); + builder.RegisterType().As(); builder.RegisterType(); } diff --git a/src/Orchard.Tests/UI/ShapeTests.cs b/src/Orchard.Tests/UI/ShapeTests.cs index f5d8fb4c0..efac540ea 100644 --- a/src/Orchard.Tests/UI/ShapeTests.cs +++ b/src/Orchard.Tests/UI/ShapeTests.cs @@ -19,7 +19,7 @@ namespace Orchard.Tests.UI { protected override void Register(ContainerBuilder builder) { builder.RegisterType().As(); - builder.RegisterType().As(); + builder.RegisterType().As(); builder.RegisterType().As(); builder.RegisterType().As(); builder.RegisterType().As(); diff --git a/src/Orchard.Web/Core/Common/Handlers/CommonPartHandler.cs b/src/Orchard.Web/Core/Common/Handlers/CommonPartHandler.cs index c012a3ddb..0c939952f 100644 --- a/src/Orchard.Web/Core/Common/Handlers/CommonPartHandler.cs +++ b/src/Orchard.Web/Core/Common/Handlers/CommonPartHandler.cs @@ -1,7 +1,6 @@ using System.Linq; using JetBrains.Annotations; using Orchard.ContentManagement.MetaData; -using Orchard.ContentManagement.MetaData.Models; using Orchard.Core.Common.Models; using Orchard.Data; using Orchard.Localization; @@ -67,9 +66,11 @@ namespace Orchard.Core.Common.Handlers { bool ContentTypeWithACommonPart(string typeName) { //Note: What about content type handlers which activate "CommonPart" in code? var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(typeName); - if (contentTypeDefinition == null) - return false; - return contentTypeDefinition.Parts.Any(part => part.PartDefinition.Name == "CommonPart"); + + if (contentTypeDefinition != null) + return contentTypeDefinition.Parts.Any(part => part.PartDefinition.Name == "CommonPart"); + + return false; } void AssignCreatingOwner(InitializingContentContext context, CommonPart part) { diff --git a/src/Orchard.Web/Modules/Orchard.Blogs/Views/Parts/Blogs.Blog.Description.cshtml b/src/Orchard.Web/Modules/Orchard.Blogs/Views/Parts/Blogs.Blog.Description.cshtml index 1610e4211..08c88c604 100644 --- a/src/Orchard.Web/Modules/Orchard.Blogs/Views/Parts/Blogs.Blog.Description.cshtml +++ b/src/Orchard.Web/Modules/Orchard.Blogs/Views/Parts/Blogs.Blog.Description.cshtml @@ -1,5 +1,5 @@ @if (HasText(Model.Description)) { -
+

@Model.Description

} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Setup/SetupMode.cs b/src/Orchard.Web/Modules/Orchard.Setup/SetupMode.cs index bd77e21af..f7f185abb 100644 --- a/src/Orchard.Web/Modules/Orchard.Setup/SetupMode.cs +++ b/src/Orchard.Web/Modules/Orchard.Setup/SetupMode.cs @@ -45,6 +45,8 @@ namespace Orchard.Setup { // standard services needed in setup mode builder.RegisterModule(new MvcModule()); builder.RegisterModule(new CommandModule()); + builder.RegisterModule(new WorkContextModule()); + builder.RegisterType().As().InstancePerLifetimeScope(); builder.RegisterType().As().InstancePerLifetimeScope(); builder.RegisterType().As().As().InstancePerLifetimeScope(); @@ -58,7 +60,7 @@ namespace Orchard.Setup { builder.RegisterType().As().InstancePerLifetimeScope(); builder.RegisterType().As().InstancePerLifetimeScope(); builder.RegisterType().As().InstancePerLifetimeScope(); - builder.RegisterType().As().InstancePerMatchingLifetimeScope("shell"); + builder.RegisterType().As().InstancePerMatchingLifetimeScope("shell"); builder.RegisterType().As().InstancePerLifetimeScope(); builder.RegisterType().As().InstancePerLifetimeScope(); builder.RegisterType().As().InstancePerLifetimeScope(); diff --git a/src/Orchard.Web/Modules/Orchard.Users/Services/UserService.cs b/src/Orchard.Web/Modules/Orchard.Users/Services/UserService.cs index ae4951d35..a1ed2f3fc 100644 --- a/src/Orchard.Web/Modules/Orchard.Users/Services/UserService.cs +++ b/src/Orchard.Web/Modules/Orchard.Users/Services/UserService.cs @@ -38,32 +38,30 @@ namespace Orchard.Users.Services { public ILogger Logger { get; set; } public string VerifyUserUnicity(string userName, string email) { - IEnumerable allUsers = _contentManager.Query().List(); + string normalizedUserName = userName.ToLower(); - foreach (var user in allUsers) { - if (String.Equals(userName.ToLower(), user.NormalizedUserName, StringComparison.OrdinalIgnoreCase)) { - return "A user with that name already exists"; - } - if (String.Equals(email, user.Email, StringComparison.OrdinalIgnoreCase)) { - return "A user with that email already exists"; - } + if (_contentManager.Query() + .Where(user => + user.NormalizedUserName == normalizedUserName || + user.Email == email) + .List().Any()) { + return "User with that username and/or email already exists."; } return null; } public string VerifyUserUnicity(int id, string userName, string email) { - IEnumerable allUsers = _contentManager.Query().List(); - foreach (var user in allUsers) { - if (user.Id == id) - continue; - if (String.Equals(userName.ToLower(), user.NormalizedUserName, StringComparison.OrdinalIgnoreCase)) { - return "A user with that name already exists"; - } - if (String.Equals(email, user.Email, StringComparison.OrdinalIgnoreCase)) { - return "A user with that email already exists"; - } + string normalizedUserName = userName.ToLower(); + + if (_contentManager.Query() + .Where(user => + user.NormalizedUserName == normalizedUserName || + user.Email == email) + .List().Any(user => user.Id != id)) { + return "User with that username and/or email already exists."; } + return null; } diff --git a/src/Orchard.Web/Themes/TheThemeMachine/Styles/Site.css b/src/Orchard.Web/Themes/TheThemeMachine/Styles/Site.css index 100725b95..2fa19a380 100644 --- a/src/Orchard.Web/Themes/TheThemeMachine/Styles/Site.css +++ b/src/Orchard.Web/Themes/TheThemeMachine/Styles/Site.css @@ -321,26 +321,25 @@ nav ul /* Main ***************************************************************/ -/* Blogs */ -.blog-description { font-size: 1.231em; } -.blog-post .tags { margin-top: 12px; } -.blog-post .tags a { background-color: #dbdbdb; padding: 3px; color: #434343; } -.blog-post .tags a:hover { background-color: #434343; padding: 3px; color: #fff; } -.blog-posts { padding: 0; margin: 0; list-style: none; } -.blog-posts li { padding: 0; margin: 0; } -.blog-posts .blog-post { border-top: 1px solid #dbdbdb; padding: 6px 0 6px 0; } -.blog-posts .blog-post header {} -.blog-posts .blog-post header h1 { font-size: 1.308em; } -.blog-posts .blog-post header h1 a { color: #434343; } -.blog-posts .blog-post header h1 a:hover {} -.blog-posts .blog-post .tags { margin-top: 12px; } -.blog-posts .blog-post .tags a { background-color: #dbdbdb; padding: 3px; color: #434343; } -.blog-posts .blog-post .tags a:hover { background-color: #434343; padding: 3px; color: #fff; text-decoration: none; } -.blog-posts .blog-post .metadata { margin: 0 0 12px 0; color: #999; font-size: 0.846em; } -.blog-posts .blog-post .metadata .published { display: inline; margin: 0 6px 0 0; } -.blog-posts .blog-post .metadata .commentcount { display: inline; } -.blog-post {} -.blog-post-title {} +/* Content lists and details */ +.content-description { font-size: 1.154em; } +.content-items { padding: 0; margin: 0; list-style: none; } +.content-items li { padding: 0; margin: 0; } +.content-items .content-item { border-top: 1px solid #dbdbdb; padding: 6px 0 6px 0; } +.content-items .content-item header {} +.content-items .content-item header h1 { font-size: 1.308em; color:#ff0000; } +.content-items .content-item header h1 a { color: #434343; } +.content-items .content-item header h1 a:hover {} + +/* Tags */ +.tags { margin-top: 12px; } +.tags a { background-color: #dbdbdb; padding: 3px 6px; color: #434343; } +.tags a:hover { background-color: #434343; padding: 3px; color: #fff; } + +/* Metadata */ +.metadata { margin: 0 0 12px 0; color: #999; font-size: 0.846em; } +.metadata .published { display: inline; margin: 0 6px 0 0; } +.metadata .commentcount { display: inline; } .meta {} /* Comments */ @@ -359,38 +358,6 @@ nav ul .comment-disabled {} .comment-count { font-size: 1.231em; } -/* Tag Search */ -.tagged-posts {} -.tagged-posts { padding: 0; margin: 0; list-style: none; } -.tagged-posts li { padding: 0; margin: 0; } -.tagged-posts .blog-post { border-top: 1px solid #dbdbdb; padding: 6px 0 6px 0; } -.tagged-posts .blog-post header {} -.tagged-posts .blog-post header h1 { font-size: 1.308em; } -.tagged-posts .blog-post header h1 a { color: #434343; } -.tagged-posts .blog-post header h1 a:hover {} -.tagged-posts .blog-post .tags { margin-top: 12px; } -.tagged-posts .blog-post .tags a { background-color: #dbdbdb; padding: 3px; color: #434343; } -.tagged-posts .blog-post .tags a:hover { background-color: #434343; padding: 3px; color: #fff; text-decoration: none; } -.tagged-posts .blog-post .metadata { margin: 0 0 12px 0; color: #999; font-size: 1.1em; } -.tagged-posts .blog-post .metadata .published { display: inline; margin: 0 6px 0 0; } -.tagged-posts .blog-post .metadata .commentcount { display: inline; } - -/* Search Results */ -.search-results {} -.search-results { padding: 0; margin: 0; list-style: none; } -.search-results li { padding: 0; margin: 0; } -.search-results .blog-post { border-top: 1px solid #dbdbdb; padding: 6px 0 6px 0; } -.search-results .blog-post header {} -.search-results .blog-post header h1 { font-size: 1.308em; } -.search-results .blog-post header h1 a { color: #434343; } -.search-results .blog-post header h1 a:hover {} -.search-results .blog-post .tags { margin-top: 12px; } -.search-results .blog-post .tags a { background-color: #dbdbdb; padding: 3px; color: #434343; } -.search-results .blog-post .tags a:hover { background-color: #434343; padding: 3px; color: #fff; text-decoration: none; } -.search-results .blog-post .metadata { margin: 0 0 12px 0; color: #999; font-size: 0.846em; } -.search-results .blog-post .metadata .published { display: inline; margin: 0 6px 0 0; } -.search-results .blog-post .metadata .commentcount { display: inline; } - /* Confirmations */ .message, .validation-summary-errors { margin:10px 0 4px 0; padding:4px; } .messages a { font-weight:bold; } @@ -455,18 +422,11 @@ nav ul /* Widgets ***************************************************************/ .widgets {} +.widget h1 { font-size: 1.077em; } /* Search */ /* Search widget shuld go into the sidebar for proper styling */ /* TODO: (mibach) Generic any zone compatible search widget */ -.widget-search-form -{ - position: absolute; - top: 30px; - right: 12px; -} -.widget-search-form h1 { font-size: 1.077em; } - .search-form {} .search-form input[type="text"] { float: left; } .search-form button[type="submit"] { float: left; margin: 0; margin-left: 6px; } @@ -477,12 +437,6 @@ nav ul .widget-control .manage-actions { position:absolute; top: 0px; right: 0px; } .widget-control .manage-actions a { display: block; background-color: #dbdbdb; color: #434343; padding: 3px 6px; } .widget-control .manage-actions a:hover { background-color: #434343; color: #fff; text-decoration: none; } -.widget-control .widget-search-form /* TODO: (mibach) Remove special case for Search Widget */ -{ - position: absolute; - top: 0px; - right: 12px; -} /* Content Mode */ .content-control { position: relative; border: 1px dotted #5f97af; } diff --git a/src/Orchard/Environment/DefaultWorkContextAccessor.cs b/src/Orchard/Environment/WorkContextAccessor.cs similarity index 60% rename from src/Orchard/Environment/DefaultWorkContextAccessor.cs rename to src/Orchard/Environment/WorkContextAccessor.cs index 9a2c6816f..307ed2dd2 100644 --- a/src/Orchard/Environment/DefaultWorkContextAccessor.cs +++ b/src/Orchard/Environment/WorkContextAccessor.cs @@ -1,13 +1,11 @@ using System; using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Linq; using System.Web; using Autofac; using Orchard.Mvc; namespace Orchard.Environment { - public class DefaultWorkContextAccessor : IWorkContextAccessor { + public class WorkContextAccessor : IWorkContextAccessor { readonly ILifetimeScope _lifetimeScope; readonly IHttpContextAccessor _httpContextAccessor; @@ -18,7 +16,7 @@ namespace Orchard.Environment { [ThreadStatic] static ConcurrentDictionary _threadStaticContexts; - public DefaultWorkContextAccessor( + public WorkContextAccessor( IHttpContextAccessor httpContextAccessor, ILifetimeScope lifetimeScope) { _httpContextAccessor = httpContextAccessor; @@ -39,36 +37,23 @@ namespace Orchard.Environment { } public IWorkContextScope CreateWorkContextScope(HttpContextBase httpContext) { + var workLifetime = _lifetimeScope.BeginLifetimeScope("work"); + workLifetime.Resolve>().Value = httpContext; - var workLifetime = SpawnWorkLifetime(builder => { - builder.Register(ctx => httpContext) - .As(); - - builder.Register(ctx => new WorkContextImplementation(ctx)) - .As() - .InstancePerMatchingLifetimeScope("work"); - }); return new HttpContextScopeImplementation( workLifetime, httpContext, _workContextKey); } + public IWorkContextScope CreateWorkContextScope() { var httpContext = _httpContextAccessor.Current(); if (httpContext != null) return CreateWorkContextScope(httpContext); - var workLifetime = SpawnWorkLifetime(builder => { - builder.Register(ctx => httpContext) - .As(); - - builder.Register(ctx => new WorkContextImplementation(ctx)) - .As() - .InstancePerMatchingLifetimeScope("work"); - }); return new ThreadStaticScopeImplementation( - workLifetime, + _lifetimeScope.BeginLifetimeScope("work"), EnsureThreadStaticContexts(), _workContextKey); } @@ -77,49 +62,6 @@ namespace Orchard.Environment { return _threadStaticContexts ?? (_threadStaticContexts = new ConcurrentDictionary()); } - private ILifetimeScope SpawnWorkLifetime(Action configurationAction) { - return _lifetimeScope.BeginLifetimeScope("work", configurationAction); - } - - class WorkContextImplementation : WorkContext { - readonly IComponentContext _componentContext; - readonly ConcurrentDictionary> _stateResolvers = new ConcurrentDictionary>(); - readonly IEnumerable _workContextStateProviders; - - public WorkContextImplementation(IComponentContext componentContext) { - _componentContext = componentContext; - _workContextStateProviders = componentContext.Resolve>(); - } - - public override T Resolve() { - return _componentContext.Resolve(); - } - - public override bool TryResolve(out T service) { - return _componentContext.TryResolve(out service); - } - - public override T GetState(string name) { - var resolver = _stateResolvers.GetOrAdd(name, FindResolverForState); - return (T)resolver(); - } - - Func FindResolverForState(string name) { - var resolver = _workContextStateProviders.Select(wcsp => wcsp.Get(name)) - .FirstOrDefault(value => !Equals(value, default(T))); - - if (resolver == null) { - return () => default(T); - } - return () => resolver(this); - } - - - public override void SetState(string name, T value) { - _stateResolvers[name] = () => value; - } - } - class HttpContextScopeImplementation : IWorkContextScope { readonly WorkContext _workContext; diff --git a/src/Orchard/Environment/WorkContextImplementation.cs b/src/Orchard/Environment/WorkContextImplementation.cs new file mode 100644 index 000000000..e7f0634b2 --- /dev/null +++ b/src/Orchard/Environment/WorkContextImplementation.cs @@ -0,0 +1,45 @@ +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Linq; +using Autofac; + +namespace Orchard.Environment { + class WorkContextImplementation : WorkContext { + readonly IComponentContext _componentContext; + readonly ConcurrentDictionary> _stateResolvers = new ConcurrentDictionary>(); + readonly IEnumerable _workContextStateProviders; + + public WorkContextImplementation(IComponentContext componentContext) { + _componentContext = componentContext; + _workContextStateProviders = componentContext.Resolve>(); + } + + public override T Resolve() { + return _componentContext.Resolve(); + } + + public override bool TryResolve(out T service) { + return _componentContext.TryResolve(out service); + } + + public override T GetState(string name) { + var resolver = _stateResolvers.GetOrAdd(name, FindResolverForState); + return (T)resolver(); + } + + Func FindResolverForState(string name) { + var resolver = Enumerable.FirstOrDefault(_workContextStateProviders.Select(wcsp => wcsp.Get(name)), value => !Equals(value, default(T))); + + if (resolver == null) { + return () => default(T); + } + return () => resolver(this); + } + + + public override void SetState(string name, T value) { + _stateResolvers[name] = () => value; + } + } +} \ No newline at end of file diff --git a/src/Orchard/Environment/WorkContextModule.cs b/src/Orchard/Environment/WorkContextModule.cs new file mode 100644 index 000000000..49729cda2 --- /dev/null +++ b/src/Orchard/Environment/WorkContextModule.cs @@ -0,0 +1,24 @@ +using System.Web; +using Autofac; + +namespace Orchard.Environment { + public class WorkContextModule : Module { + protected override void Load(ContainerBuilder builder) { + builder.RegisterType() + .As() + .InstancePerMatchingLifetimeScope("shell"); + + builder.Register(ctx => new WorkContextImplementation(ctx)) + .As() + .InstancePerMatchingLifetimeScope("work"); + + builder.RegisterType>() + .As>() + .InstancePerMatchingLifetimeScope("work"); + + builder.Register(ctx => ctx.Resolve>().Value) + .As() + .InstancePerDependency(); + } + } +} diff --git a/src/Orchard/Environment/WorkContextProperty.cs b/src/Orchard/Environment/WorkContextProperty.cs new file mode 100644 index 000000000..8dd6223d0 --- /dev/null +++ b/src/Orchard/Environment/WorkContextProperty.cs @@ -0,0 +1,5 @@ +namespace Orchard.Environment { + class WorkContextProperty { + public T Value { get; set; } + } +} \ No newline at end of file diff --git a/src/Orchard/IWorkContextAccessor.cs b/src/Orchard/IWorkContextAccessor.cs index 585b630a4..1f6fec307 100644 --- a/src/Orchard/IWorkContextAccessor.cs +++ b/src/Orchard/IWorkContextAccessor.cs @@ -2,7 +2,7 @@ using System.Web; namespace Orchard { - public interface IWorkContextAccessor : ISingletonDependency { + public interface IWorkContextAccessor { WorkContext GetContext(HttpContextBase httpContext); IWorkContextScope CreateWorkContextScope(HttpContextBase httpContext); diff --git a/src/Orchard/Mvc/OrchardControllerFactory.cs b/src/Orchard/Mvc/OrchardControllerFactory.cs index f4596c66b..c66ab2d7e 100644 --- a/src/Orchard/Mvc/OrchardControllerFactory.cs +++ b/src/Orchard/Mvc/OrchardControllerFactory.cs @@ -36,10 +36,10 @@ namespace Orchard.Mvc { var serviceKey = (areaName + "/" + controllerName).ToLowerInvariant(); // Now that the request container is known - try to resolve the controller information - Lazy> info; + Meta> info; var workContext = requestContext.GetWorkContext(); if (TryResolve(workContext, serviceKey, out info)) { - return (Type) info.Value.Metadata["ControllerType"]; + return (Type) info.Metadata["ControllerType"]; } return null; diff --git a/src/Orchard/Orchard.Framework.csproj b/src/Orchard/Orchard.Framework.csproj index a264d31e6..b54a863e2 100644 --- a/src/Orchard/Orchard.Framework.csproj +++ b/src/Orchard/Orchard.Framework.csproj @@ -158,6 +158,9 @@ + + + @@ -419,7 +422,7 @@ - +