Moving controllers out of stock Orchard.Web app. Updating standard route provider to use package manager active entry information. (removes hardcoded entries.)

--HG--
extra : convert_revision : svn%3A5ff7c347-ad56-4c35-b696-ccb81de16e03/trunk%4039327
This commit is contained in:
loudej 2009-11-10 07:39:09 +00:00
parent 0eaf1ccb30
commit ef0c573f42
23 changed files with 204 additions and 176 deletions

View File

@ -0,0 +1,58 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Routing;
using NUnit.Framework;
using Orchard.Mvc.Routes;
using Orchard.Packages;
namespace Orchard.Tests.Mvc.Routes {
[TestFixture]
public class StandardPackageRouteProviderTests {
[Test]
public void PackageDisplayNameShouldBeUsedInBothStandardRoutes() {
var stubManager = new StubPackageManager();
var routeProvider = new StandardPackageRouteProvider(stubManager);
var routes = new List<RouteDescriptor>();
routeProvider.GetRoutes(routes);
Assert.That(routes, Has.Count.EqualTo(4));
var fooAdmin = routes.Select(x => x.Route).OfType<Route>()
.Single(x => x.Url == "Admin/Foo/{action}/{id}");
var fooRoute = routes.Select(x => x.Route).OfType<Route>()
.Single(x => x.Url == "Foo/{controller}/{action}/{id}");
var barAdmin = routes.Select(x => x.Route).OfType<Route>()
.Single(x => x.Url == "Admin/Bar/{action}/{id}");
var barRoute = routes.Select(x => x.Route).OfType<Route>()
.Single(x => x.Url == "Bar/{controller}/{action}/{id}");
Assert.That(fooAdmin.DataTokens["area"], Is.EqualTo("Long.Name.Foo"));
Assert.That(fooRoute.DataTokens["area"], Is.EqualTo("Long.Name.Foo"));
Assert.That(barAdmin.DataTokens["area"], Is.EqualTo("Long.Name.Bar"));
Assert.That(barRoute.DataTokens["area"], Is.EqualTo("Long.Name.Bar"));
}
public class StubPackageManager : IPackageManager {
public IEnumerable<PackageDescriptor> AvailablePackages() {
throw new NotImplementedException();
}
public IEnumerable<PackageEntry> ActivePackages() {
yield return new PackageEntry {
Descriptor = new PackageDescriptor {
Name = "Long.Name.Foo",
DisplayName = "Foo",
}
};
yield return new PackageEntry {
Descriptor = new PackageDescriptor {
Name = "Long.Name.Bar",
DisplayName = "Bar",
}
};
}
}
}
}

View File

@ -122,6 +122,7 @@
<Compile Include="Mvc\OrchardControllerFactoryTests.cs" />
<Compile Include="Mvc\OrchardControllerIdentificationStrategyTests.cs" />
<Compile Include="Mvc\RouteCollectionPublisherTests.cs" />
<Compile Include="Mvc\Routes\StandardPackageRouteProviderTests.cs" />
<Compile Include="Notify\NotifierTests.cs" />
<Compile Include="Notify\NotifyFilterTests.cs" />
<Compile Include="Packages\PackageFoldersTests.cs" />

View File

@ -74,5 +74,6 @@ version: 2.x
Assert.That(descriptor.Description, Is.EqualTo("This is the description"));
Assert.That(descriptor.Version, Is.EqualTo("2.x"));
}
}
}

View File

@ -1,18 +0,0 @@
using System.Web.Mvc;
using NUnit.Framework;
using Orchard.Web.Controllers;
namespace Orchard.Web.Tests.Controllers {
[TestFixture]
public class HomeControllerTests {
[Test]
public void IndexAndAboutShouldReturnViews() {
var controller = new HomeController();
var result1 = controller.Index();
var result2 = controller.About();
Assert.That(result1, Is.TypeOf<ViewResult>());
Assert.That(result2, Is.TypeOf<ViewResult>());
}
}
}

View File

@ -60,7 +60,6 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Controllers\HomeControllerTests.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Routes\RouteTests.cs" />
<Compile Include="Stubs\StubContext.cs" />

View File

@ -1,54 +0,0 @@
using System.Collections.Generic;
using System.Web.Mvc;
using Orchard.Mvc.ModelBinders;
namespace Orchard.Web.Controllers {
[HandleError]
public class HomeController : Controller {
static HomeController() {
var fooListBinder = new KeyedListModelBinder<Foo>(
ModelBinders.Binders, ModelMetadataProviders.Current, x => x.Name);
ModelBinders.Binders.Add(typeof(IList<Foo>), fooListBinder);
}
public ActionResult Index() {
ViewData["Message"] = "Welcome to ASP.NET MVC!";
return View();
}
public ActionResult About() {
var foos = new[] {
new Foo {Name = "one", Content = "uno"},
new Foo {Name = "two", Content = "dos"},
new Foo {Name = "three", Content = "tres"},
};
return View(new HomeAboutViewModel { Foos = foos });
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult About(FormCollection input) {
var foos = new[] {
new Foo {Name = "one", Content = "uno"},
new Foo {Name = "two", Content = "dos"},
new Foo {Name = "three", Content = "tres"},
};
var vm = new HomeAboutViewModel { Foos = foos };
UpdateModel(vm, input.ToValueProvider());
return RedirectToAction("About");
}
}
public class Foo {
public string Name { get; set; }
public string Content { get; set; }
}
public class HomeAboutViewModel {
public IList<Foo> Foos { get; set; }
}
}

View File

@ -82,8 +82,6 @@
<Reference Include="System.Web.Mobile" />
</ItemGroup>
<ItemGroup>
<Compile Include="Controllers\AccountController.cs" />
<Compile Include="Controllers\HomeController.cs" />
<Compile Include="Default.aspx.cs">
<DependentUpon>Default.aspx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
@ -134,6 +132,10 @@
<Project>{79AED36E-ABD0-4747-93D3-8722B042454B}</Project>
<Name>Orchard.Users</Name>
</ProjectReference>
<ProjectReference Include="Packages\TinyMce\TinyMce.csproj">
<Project>{954CA994-D204-468B-9D69-51F6AD3E1C29}</Project>
<Name>TinyMce</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Content Include="Content\Admin\images\background_header.jpg" />
@ -162,7 +164,6 @@
</ItemGroup>
<ItemGroup>
<Folder Include="App_Data\" />
<Folder Include="Models\" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v9.0\WebApplications\Microsoft.WebApplication.targets" />

View File

@ -120,6 +120,7 @@
<Content Include="Content\Admin\images\online.gif" />
<Content Include="Content\Admin\images\published.gif" />
<Content Include="Content\Admin\images\scheduled.gif" />
<Content Include="Package.txt" />
<Content Include="Views\Admin\ChooseTemplate.aspx" />
<Content Include="Views\Admin\BulkDeleteConfirm.aspx" />
<Content Include="Views\Admin\BulkPublishLater.aspx" />

View File

@ -89,6 +89,7 @@
</ItemGroup>
<ItemGroup>
<Content Include="Content\Admin\images\folder.gif" />
<Content Include="Package.txt" />
<Content Include="Views\Admin\Add.aspx" />
<Content Include="Views\Admin\Create.aspx" />
<Content Include="Views\Admin\Edit.aspx" />

View File

@ -66,6 +66,7 @@
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<Content Include="Package.txt" />
<Content Include="Web.config" />
<Content Include="Views\Web.config" />
</ItemGroup>

View File

@ -64,6 +64,7 @@
<Reference Include="System.Web.Mobile" />
</ItemGroup>
<ItemGroup>
<Content Include="Package.txt" />
<Content Include="Views\Home\Index.aspx" />
<Content Include="Web.config" />
</ItemGroup>

View File

@ -59,6 +59,7 @@
<Reference Include="System.Web.Mobile" />
</ItemGroup>
<ItemGroup>
<Content Include="Package.txt" />
<Content Include="Scripts\langs\en.js" />
<Content Include="Scripts\license.txt" />
<Content Include="Scripts\plugins\autoresize\editor_plugin.js" />

View File

@ -1,6 +1,5 @@
<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<HomeAboutViewModel>" %>
<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>
<%@ Import Namespace="Orchard.Web.Controllers" %>
<asp:Content ID="aboutTitle" ContentPlaceHolderID="TitleContent" runat="server">
About Us
</asp:Content>
@ -10,13 +9,4 @@
<p>
Put content here.
</p>
<%using (Html.BeginForm()) { %>
<%
foreach (var foo in Model.Foos) {%>
<%=Html.TextArea("Foos[" + foo.Name + "].Content", foo.Content)%>
<%
}%>
<input type="submit" />
<%
}%>
</asp:Content>

View File

@ -5,7 +5,7 @@ using System.Security.Principal;
using System.Web.Mvc;
using System.Web.Security;
namespace Orchard.Web.Controllers {
namespace Orchard.Controllers {
[HandleError]
public class AccountController : Controller {
// This constructor is used by the MVC framework to instantiate the controller using
@ -219,11 +219,6 @@ namespace Orchard.Web.Controllers {
#endregion
}
// The FormsAuthentication type is sealed and contains static members, so it is difficult to
// unit test code that calls its members. The interface and helper class below demonstrate
// how to create an abstract wrapper around such a type in order to make the AccountController
// code unit testable.
public interface IFormsAuthentication {
void SignIn(string userName, bool createPersistentCookie);
void SignOut();

View File

@ -0,0 +1,23 @@
using System.Collections.Generic;
using System.Web.Mvc;
using Orchard.Mvc.ModelBinders;
namespace Orchard.Controllers {
[HandleError]
public class HomeController : Controller {
public ActionResult Index() {
ViewData["Message"] = "Welcome to ASP.NET MVC!";
return View();
}
public ActionResult About() {
return View();
}
}
}

View File

@ -5,6 +5,7 @@ using System.Reflection;
using System.Text;
using System.Web.Compilation;
using Autofac;
using Orchard.Packages;
namespace Orchard.Environment {
//TEMP: This will be replaced by packaging system
@ -16,8 +17,17 @@ namespace Orchard.Environment {
}
public class DefaultCompositionStrategy : ICompositionStrategy {
private readonly IPackageManager _packageManager;
public DefaultCompositionStrategy(IPackageManager packageManager) {
_packageManager = packageManager;
}
public IEnumerable<Assembly> GetAssemblies() {
return BuildManager.GetReferencedAssemblies().OfType<Assembly>();
return _packageManager.ActivePackages()
.Select(entry => entry.Assembly)
.Concat(new[]{typeof(IOrchardHost).Assembly});
//return BuildManager.GetReferencedAssemblies().OfType<Assembly>();
}
public IEnumerable<Type> GetModuleTypes() {

View File

@ -1,8 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Hosting;
using Autofac;
using Autofac.Builder;
using Autofac.Integration.Web;
using Autofac.Modules;
using Orchard.Packages;
namespace Orchard.Environment {
public static class OrchardStarter {
@ -25,6 +29,17 @@ namespace Orchard.Environment {
// still needs to be called on end request, but that's the host component's job to worry about.
builder.Register<ContainerProvider>().As<IContainerProvider>().ContainerScoped();
builder.Register<PackageManager>().As<IPackageManager>()
.SingletonScoped();
//builder.Register((ctx, p) => new PackageFolders(MapPaths(p.Named<IEnumerable<string>>("paths"))))
// .As<IPackageFolders>()
// .WithExtendedProperty("paths", new[] { "~/Packages" })
// .SingletonScoped();
builder.Register<PackageFolders>().As<IPackageFolders>()
.WithArguments(new NamedParameter("paths", new[] { "~/Packages" }))
.SingletonScoped();
registrations(builder);
return builder.Build();

View File

@ -13,7 +13,7 @@ namespace Orchard.Mvc {
var container = GetRequestContainer(routeData);
// Determine the area name for the request, and fall back to stock orchard controllers
var areaName = GetAreaName(routeData) ?? "Orchard.Web";
var areaName = GetAreaName(routeData) ?? "Orchard";
// Service name pattern matches the identification strategy
var serviceName = ("controller." + areaName + "." + controllerName).ToLowerInvariant();

View File

@ -2,78 +2,54 @@
using System.Collections.Generic;
using System.Web.Mvc;
using System.Web.Routing;
using Orchard.Packages;
namespace Orchard.Mvc.Routes {
public class StandardPackageRouteProvider : IRouteProvider {
private readonly IPackageManager _packageManager;
public StandardPackageRouteProvider(IPackageManager packageManager) {
_packageManager = packageManager;
}
public IEnumerable<RouteDescriptor> GetRoutes() {
//TEMP: Need to rely on a service that gives the list of active packages
return new[] {
new RouteDescriptor {
Priority = -10,
Route = new Route(
"Admin/Pages/{action}/{id}",
new RouteValueDictionary {
{"area", "Orchard.CmsPages"},
{"controller", "admin"},
{"action", "index"},
{"id", ""}
},
new RouteValueDictionary(),
new RouteValueDictionary {
{"area", "Orchard.CmsPages"}
},
new MvcRouteHandler())
},
new RouteDescriptor {
Priority = -10,
Route = new Route(
"Pages/{controller}/{action}/{id}",
new RouteValueDictionary {
{"area", "Orchard.CmsPages"},
{"controller", "home"},
{"action", "index"},
{"id", ""}
},
new RouteValueDictionary(),
new RouteValueDictionary {
{"area", "Orchard.CmsPages"}
},
new MvcRouteHandler())
},
new RouteDescriptor {
Priority = -10,
Route = new Route(
"Admin/Media/{action}/{id}",
new RouteValueDictionary {
{"area", "Orchard.Media"},
{"controller", "admin"},
{"action", "index"},
{"id", ""}
},
new RouteValueDictionary(),
new RouteValueDictionary {
{"area", "Orchard.Media"}
},
new MvcRouteHandler())
},
new RouteDescriptor {
Priority = -10,
Route = new Route(
"XmlRpc/{controller}/{action}/{id}",
new RouteValueDictionary {
{"area", "Orchard.XmlRpc"},
{"controller", "home"},
{"action", "index"},
{"id", ""}
},
new RouteValueDictionary(),
new RouteValueDictionary {
{"area", "Orchard.XmlRpc"},
{"namespace", "Orchard.XmlRpc.Controllers"}
},
new MvcRouteHandler())
},
};
foreach (var entry in _packageManager.ActivePackages()) {
var areaName = entry.Descriptor.Name;
var displayName = entry.Descriptor.DisplayName ?? areaName;
yield return new RouteDescriptor {
Priority = -10,
Route = new Route(
"Admin/" + displayName + "/{action}/{id}",
new RouteValueDictionary {
{"area", areaName},
{"controller", "admin"},
{"action", "index"},
{"id", ""}
},
new RouteValueDictionary(),
new RouteValueDictionary {
{"area", areaName}
},
new MvcRouteHandler())
};
yield return new RouteDescriptor {
Priority = -10,
Route = new Route(
displayName + "/{controller}/{action}/{id}",
new RouteValueDictionary {
{"area", areaName},
{"controller", "home"},
{"action", "index"},
{"id", ""}
},
new RouteValueDictionary(),
new RouteValueDictionary {
{"area", areaName}
},
new MvcRouteHandler())
};
}
}
public void GetRoutes(ICollection<RouteDescriptor> routes) {

View File

@ -117,6 +117,8 @@
<Compile Include="Validation\Argument.cs" />
</ItemGroup>
<ItemGroup>
<Compile Include="Controllers\AccountController.cs" />
<Compile Include="Controllers\HomeController.cs" />
<Compile Include="Data\Conventions\AttributeCollectionConvention.cs" />
<Compile Include="Data\Conventions\CascadeAllDeleteOrphanAttribute.cs" />
<Compile Include="Environment\ServiceLocator.cs" />

View File

@ -1,11 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
namespace Orchard.Packages {
public class PackageEntry {
public PackageDescriptor Descriptor { get; set; }
public Assembly Assembly { get; set; }
}
}

View File

@ -1,27 +1,38 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Hosting;
using Yaml.Grammar;
namespace Orchard.Packages {
public interface IPackageFolders : IDependency {
public interface IPackageFolders {
IEnumerable<string> ListNames();
YamlDocument ParseManifest(string name);
}
public class PackageFolders : IPackageFolders {
private readonly IEnumerable<string> _physicalPaths;
private readonly IEnumerable<string> _paths;
public PackageFolders(IEnumerable<string> physicalPaths) {
_physicalPaths = physicalPaths;
public PackageFolders(IEnumerable<string> paths) {
_paths = paths;
}
private IEnumerable<string> GetPhysicalPaths() {
foreach(var path in _paths) {
if (path.StartsWith("~") && HostingEnvironment.IsHosted) {
yield return HostingEnvironment.MapPath(path);
}
else {
yield return path;
}
}
}
public IEnumerable<string> ListNames() {
foreach (var path in _physicalPaths) {
foreach (var path in GetPhysicalPaths()) {
foreach (var directoryName in Directory.GetDirectories(path)) {
if (File.Exists(Path.Combine(directoryName, "Package.txt")))
yield return Path.GetFileName(directoryName);
@ -30,7 +41,7 @@ namespace Orchard.Packages {
}
public YamlDocument ParseManifest(string name) {
foreach(var path in _physicalPaths) {
foreach (var path in GetPhysicalPaths()) {
var packageDirectoryPath = Path.Combine(path, name);
var packageManifestPath = Path.Combine(packageDirectoryPath, "Package.txt");
if (!File.Exists(packageManifestPath)) {

View File

@ -1,11 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using Yaml.Grammar;
namespace Orchard.Packages {
public interface IPackageManager : IDependency {
public interface IPackageManager {
IEnumerable<PackageDescriptor> AvailablePackages();
IEnumerable<PackageEntry> ActivePackages();
}
@ -38,15 +39,26 @@ namespace Orchard.Packages {
}
private static string GetValue(
IDictionary<string, DataItem> fields,
IDictionary<string, DataItem> fields,
string key) {
DataItem value;
return fields.TryGetValue(key, out value) ? value.ToString() : null;
}
public IEnumerable<PackageEntry> ActivePackages() {
throw new NotImplementedException();
foreach (var descriptor in AvailablePackages()) {
//TODO: this component needs access to some "current settings" to know which are active
yield return BuildEntry(descriptor);
}
}
private static PackageEntry BuildEntry(PackageDescriptor descriptor) {
var entry = new PackageEntry {
Descriptor = descriptor,
Assembly = Assembly.Load(descriptor.Name)
};
return entry;
}
}