Adding some spike/concept work as context to refine model processing.

--HG--
extra : convert_revision : svn%3A5ff7c347-ad56-4c35-b696-ccb81de16e03/trunk%4041259
This commit is contained in:
loudej
2009-11-18 18:21:39 +00:00
parent 7073054037
commit 322c25df0e
27 changed files with 251 additions and 44 deletions

View File

@@ -0,0 +1,54 @@
using Orchard.Core.Common.Records;
using Orchard.Data;
using Orchard.Models;
using Orchard.Models.Driver;
using Orchard.Security;
using Orchard.Services;
namespace Orchard.Core.Common.Models {
public class CommonDriver : ModelDriverWithRecord<CommonRecord> {
private readonly IClock _clock;
private readonly IAuthenticationService _authenticationService;
private readonly IModelManager _modelManager;
public CommonDriver(
IRepository<CommonRecord> repository,
IClock clock,
IAuthenticationService authenticationService,
IModelManager modelManager)
: base(repository) {
_clock = clock;
_authenticationService = authenticationService;
_modelManager = modelManager;
}
protected override void Create(CreateModelContext context) {
var instance = context.Instance.As<CommonModel>();
if (instance != null && instance.Record != null) {
if (instance.Record.CreatedUtc == null) {
instance.Record.CreatedUtc = _clock.UtcNow;
}
if (instance.Record.ModifiedUtc == null) {
instance.Record.ModifiedUtc = _clock.UtcNow;
}
if (instance.Record.OwnerId == 0) {
instance.Owner = _authenticationService.GetAuthenticatedUser();
if (instance.Owner != null)
instance.Record.OwnerId = instance.Owner.Id;
}
}
base.Create(context);
}
protected override void Loaded(LoadModelContext context) {
var instance = context.Instance.As<CommonModel>();
if (instance != null && instance.Record != null) {
if (instance.Record.OwnerId != 0) {
instance.Owner = _modelManager.Get(instance.Record.OwnerId).As<IUser>();
}
}
base.Loaded(context);
}
}
}

View File

@@ -0,0 +1,9 @@
using Orchard.Core.Common.Records;
using Orchard.Models;
using Orchard.Security;
namespace Orchard.Core.Common.Models {
public class CommonModel : ModelPartWithRecord<CommonRecord> {
public IUser Owner { get; set; }
}
}

View File

@@ -0,0 +1,7 @@
using Orchard.Models.Driver;
namespace Orchard.Core.Common.Models {
public class ContentDriver : ModelDriver {
}
}

View File

@@ -0,0 +1,8 @@
using Orchard.Models;
namespace Orchard.Core.Common.Models {
public class ContentModel : ModelPart {
public string Body { get; set; }
public string Format { get; set; }
}
}

View File

@@ -0,0 +1,10 @@
using Orchard.Core.Common.Records;
using Orchard.Data;
using Orchard.Models.Driver;
namespace Orchard.Core.Common.Models {
public class RoutableDriver : ModelDriverWithRecord<RoutableRecord> {
public RoutableDriver(IRepository<RoutableRecord> repository) : base(repository) {
}
}
}

View File

@@ -0,0 +1,7 @@
using Orchard.Core.Common.Records;
using Orchard.Models;
namespace Orchard.Core.Common.Models {
public class RoutableModel : ModelPartWithRecord<RoutableRecord> {
}
}

View File

@@ -0,0 +1 @@
Name: Content

View File

@@ -0,0 +1,10 @@
using System;
using Orchard.Models.Records;
namespace Orchard.Core.Common.Records {
public class CommonRecord : ModelPartRecord {
public virtual int OwnerId { get; set; }
public virtual DateTime? CreatedUtc { get; set; }
public virtual DateTime? ModifiedUtc { get; set; }
}
}

View File

@@ -0,0 +1,8 @@
using Orchard.Models.Records;
namespace Orchard.Core.Common.Records {
public class RoutableRecord : ModelPartRecord {
public virtual string Title { get; set; }
public virtual string Slug { get; set; }
}
}

View File

@@ -61,6 +61,14 @@
<Reference Include="System.Web.Mobile" />
</ItemGroup>
<ItemGroup>
<Compile Include="Common\Models\CommonDriver.cs" />
<Compile Include="Common\Models\CommonModel.cs" />
<Compile Include="Common\Models\ContentDriver.cs" />
<Compile Include="Common\Models\ContentModel.cs" />
<Compile Include="Common\Models\RoutableModel.cs" />
<Compile Include="Common\Models\RoutableDriver.cs" />
<Compile Include="Common\Records\CommonRecord.cs" />
<Compile Include="Common\Records\RoutableRecord.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="XmlRpc\Controllers\HomeController.cs" />
<Compile Include="XmlRpc\Controllers\LiveWriterController.cs" />
@@ -76,6 +84,7 @@
<Compile Include="XmlRpc\XmlRpcContext.cs" />
</ItemGroup>
<ItemGroup>
<Content Include="Common\Package.txt" />
<Content Include="Web.config" />
<Content Include="XmlRpc\Package.txt" />
<Content Include="XmlRpc\Views\Home\Index.aspx" />
@@ -117,7 +126,7 @@
<WebProjectProperties>
<UseIIS>False</UseIIS>
<AutoAssignPort>True</AutoAssignPort>
<DevelopmentServerPort>52289</DevelopmentServerPort>
<DevelopmentServerPort>53609</DevelopmentServerPort>
<DevelopmentServerVPath>/</DevelopmentServerVPath>
<IISUrl>
</IISUrl>

View File

@@ -177,7 +177,7 @@
<WebProjectProperties>
<UseIIS>False</UseIIS>
<AutoAssignPort>True</AutoAssignPort>
<DevelopmentServerPort>65251</DevelopmentServerPort>
<DevelopmentServerPort>53589</DevelopmentServerPort>
<DevelopmentServerVPath>/</DevelopmentServerVPath>
<IISUrl>
</IISUrl>

View File

@@ -143,7 +143,7 @@
<WebProjectProperties>
<UseIIS>False</UseIIS>
<AutoAssignPort>True</AutoAssignPort>
<DevelopmentServerPort>65259</DevelopmentServerPort>
<DevelopmentServerPort>53597</DevelopmentServerPort>
<DevelopmentServerVPath>/</DevelopmentServerVPath>
<IISUrl>
</IISUrl>

View File

@@ -127,7 +127,7 @@
<WebProjectProperties>
<UseIIS>False</UseIIS>
<AutoAssignPort>True</AutoAssignPort>
<DevelopmentServerPort>18551</DevelopmentServerPort>
<DevelopmentServerPort>53605</DevelopmentServerPort>
<DevelopmentServerVPath>/</DevelopmentServerVPath>
<IISUrl>
</IISUrl>

View File

@@ -127,7 +127,7 @@
<WebProjectProperties>
<UseIIS>False</UseIIS>
<AutoAssignPort>True</AutoAssignPort>
<DevelopmentServerPort>65271</DevelopmentServerPort>
<DevelopmentServerPort>53601</DevelopmentServerPort>
<DevelopmentServerVPath>/</DevelopmentServerVPath>
<IISUrl>
</IISUrl>

View File

@@ -7,7 +7,7 @@ namespace Orchard.Wikis {
public void GetNavigation(NavigationBuilder builder) {
builder.Add("Wiki", "9",
menu => menu
.Add("Wiki Pages", "1.0", item => item.Action("Index", "Admin", new { area = "Orchard.Wiki" }))
.Add("Wiki Pages", "1.0", item => item.Action("Index", "Admin", new { area = "Orchard.Wikis" }))
);
}
}

View File

@@ -1,13 +1,33 @@
using System.Web.Mvc;
using Orchard.Core.Common.Models;
using Orchard.Models;
using Orchard.Mvc.ViewModels;
using Orchard.Security;
namespace Orchard.Wikis.Controllers
{
public class AdminController : Controller
{
public ActionResult Index()
{
namespace Orchard.Wikis.Controllers {
public class AdminController : Controller {
private readonly IModelManager _modelManager;
public AdminController(IModelManager modelManager) {
_modelManager = modelManager;
}
public ActionResult Index() {
return View(new AdminViewModel());
}
public IUser CurrentUser { get; set; }
public ActionResult Create() {
var page = _modelManager.New("wikipage");
_modelManager.Create(page);
return RedirectToAction("View", new{page.Id});
}
public ActionResult View(int id) {
var page = _modelManager.Get(id).As<CommonModel>();
return View(page);
}
}
}

View File

@@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Orchard.Core.Common.Models;
using Orchard.Models.Driver;
namespace Orchard.Wikis.Models {
public class WikiPageDriver : ModelDriver {
protected override void New(NewModelContext context) {
if (context.ModelType == "wikipage") {
context.Builder
.Weld<CommonModel>()
.Weld<RoutableModel>()
.Weld<ContentModel>();
}
}
}
}

View File

@@ -63,6 +63,7 @@
<ItemGroup>
<Compile Include="AdminMenu.cs" />
<Compile Include="Controllers\AdminController.cs" />
<Compile Include="Models\WikiPageDriver.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
@@ -76,11 +77,14 @@
<Project>{2D1D92BB-4555-4CBE-8D0E-63563D6CE4C6}</Project>
<Name>Orchard</Name>
</ProjectReference>
<ProjectReference Include="..\..\Core\Orchard.Core.csproj">
<Project>{9916839C-39FC-4CEB-A5AF-89CA7E87119F}</Project>
<Name>Orchard.Core</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Folder Include="App_Data\" />
<Folder Include="Content\" />
<Folder Include="Models\" />
<Folder Include="Scripts\" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
@@ -114,7 +118,7 @@
<WebProjectProperties>
<UseIIS>False</UseIIS>
<AutoAssignPort>True</AutoAssignPort>
<DevelopmentServerPort>1275</DevelopmentServerPort>
<DevelopmentServerPort>53613</DevelopmentServerPort>
<DevelopmentServerVPath>/</DevelopmentServerVPath>
<IISUrl>
</IISUrl>

View File

@@ -14,6 +14,7 @@
<% Html.BeginForm(); %>
<div class="yui-g">
<h2>Wiki Admin</h2>
<p><%=Html.ActionLink("Create", "Create") %></p>
</div>
<% Html.EndForm(); %>
<% Html.Include("Footer"); %>

View File

@@ -151,7 +151,7 @@
<WebProjectProperties>
<UseIIS>False</UseIIS>
<AutoAssignPort>True</AutoAssignPort>
<DevelopmentServerPort>65255</DevelopmentServerPort>
<DevelopmentServerPort>53593</DevelopmentServerPort>
<DevelopmentServerVPath>/</DevelopmentServerVPath>
<IISUrl>
</IISUrl>

View File

@@ -8,6 +8,7 @@ using FluentNHibernate.Cfg;
using FluentNHibernate.Cfg.Db;
using NHibernate;
using NHibernate.Tool.hbm2ddl;
using Orchard.Models;
namespace Orchard.Data {
public class HackSessionLocator : ISessionLocator, IDisposable {
@@ -28,6 +29,7 @@ namespace Orchard.Data {
CreatePersistenceModel(Assembly.Load("Orchard.Users")),
CreatePersistenceModel(Assembly.Load("Orchard.Roles")),
CreatePersistenceModel(Assembly.Load("Orchard")),
CreatePersistenceModel(Assembly.Load("Orchard.Core")),
};
return _sessionFactory ??
@@ -48,18 +50,19 @@ namespace Orchard.Data {
private static AutoPersistenceModel CreatePersistenceModel(Assembly assembly) {
return AutoMap.Assembly(assembly)
.Where(IsModelType)
.Where(IsRecordType)
.Alterations(alt => alt
.Add(new AutoMappingOverrideAlteration(assembly))
.AddFromAssemblyOf<DataModule>())
.Conventions.AddFromAssemblyOf<DataModule>();
}
private static bool IsModelType(Type type) {
private static bool IsRecordType(Type type) {
return (type.Namespace.EndsWith(".Models") || type.Namespace.EndsWith(".Records")) &&
type.GetProperty("Id") != null &&
!type.IsSealed &&
!type.IsAbstract;
!type.IsAbstract &&
!typeof(IModel).IsAssignableFrom(type);
}
public ISession For(Type entityType) {

View File

@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Web.Mvc;
using Autofac;
using Orchard.Data;
using Orchard.Models.Driver;
using Orchard.Models.Records;
@@ -8,19 +9,28 @@ using Orchard.UI.Models;
namespace Orchard.Models {
public class DefaultModelManager : IModelManager {
private readonly IEnumerable<IModelDriver> _drivers;
private readonly IContext _context;
private readonly IRepository<ModelRecord> _modelRepository;
private readonly IRepository<ModelTypeRecord> _modelTypeRepository;
public DefaultModelManager(
IEnumerable<IModelDriver> drivers,
IContext context,
IRepository<ModelRecord> modelRepository,
IRepository<ModelTypeRecord> modelTypeRepository) {
_drivers = drivers;
_context = context;
_modelRepository = modelRepository;
_modelTypeRepository = modelTypeRepository;
}
private IEnumerable<IModelDriver> _drivers;
public IEnumerable<IModelDriver> Drivers {
get {
if (_drivers == null)
_drivers = _context.Resolve<IEnumerable<IModelDriver>>();
return _drivers;
}
}
public virtual IModel New(string modelType) {
// create a new kernel for the model instance
@@ -30,12 +40,19 @@ namespace Orchard.Models {
};
// invoke drivers to weld aspects onto kernel
foreach (var driver in _drivers) {
foreach (var driver in Drivers) {
driver.New(context);
}
var context2 = new NewedModelContext {
ModelType = modelType,
Instance = context.Builder.Build()
};
foreach (var driver in Drivers) {
driver.Newed(context2);
}
// composite result is returned
return context.Builder.Build();
return context2.Instance;
}
public virtual IModel Get(int id) {
@@ -54,9 +71,12 @@ namespace Orchard.Models {
context.Instance.As<ModelRoot>().Id = context.Id;
// invoke drivers to acquire state, or at least establish lazy loading callbacks
foreach (var driver in _drivers) {
foreach (var driver in Drivers) {
driver.Load(context);
}
foreach (var driver in Drivers) {
driver.Loaded(context);
}
return context.Instance;
}
@@ -79,14 +99,17 @@ namespace Orchard.Models {
// invoke drivers to add information to persistent stores
foreach (var driver in _drivers) {
foreach (var driver in Drivers) {
driver.Create(context);
}
foreach (var driver in Drivers) {
driver.Created(context);
}
}
public IEnumerable<ModelTemplate> GetEditors(IModel model) {
var context = new GetModelEditorsContext(model);
foreach (var driver in _drivers) {
foreach (var driver in Drivers) {
driver.GetEditors(context);
}
return context.Editors;
@@ -94,7 +117,7 @@ namespace Orchard.Models {
public IEnumerable<ModelTemplate> UpdateEditors(IModel model, IModelUpdater updater) {
var context = new UpdateModelContext(model, updater);
foreach (var driver in _drivers) {
foreach (var driver in Drivers) {
driver.UpdateEditors(context);
}
return context.Editors;

View File

@@ -1,8 +1,11 @@
namespace Orchard.Models.Driver {
public interface IModelDriver : IDependency {
void New(NewModelContext context);
void Newed(NewedModelContext context);
void Create(CreateModelContext context);
void Created(CreateModelContext context);
void Load(LoadModelContext context);
void Loaded(LoadModelContext context);
void GetEditors(GetModelEditorsContext context);
void UpdateEditors(UpdateModelContext context);

View File

@@ -7,27 +7,28 @@ namespace Orchard.Models.Driver {
Logger = NullLogger.Instance;
}
public ILogger Logger{ get; set;}
public ILogger Logger { get; set; }
void IModelDriver.New(NewModelContext context) {New(context);}
void IModelDriver.New(NewModelContext context) { New(context); }
void IModelDriver.Newed(NewedModelContext context) { Newed(context); }
void IModelDriver.Create(CreateModelContext context) { Create(context); }
void IModelDriver.Created(CreateModelContext context) { Created(context); }
void IModelDriver.Load(LoadModelContext context) { Load(context); }
void IModelDriver.Loaded(LoadModelContext context) { Loaded(context); }
void IModelDriver.GetEditors(GetModelEditorsContext context) { GetEditors(context); }
void IModelDriver.UpdateEditors(UpdateModelContext context) { UpdateEditors(context); }
protected virtual void New(NewModelContext context) {
}
protected virtual void New(NewModelContext context) { }
protected virtual void Newed(NewedModelContext context) { }
protected virtual void Load(LoadModelContext context) {
}
protected virtual void Load(LoadModelContext context) { }
protected virtual void Loaded(LoadModelContext context) { }
protected virtual void Create(CreateModelContext context) {
}
protected virtual void Create(CreateModelContext context) { }
protected virtual void Created(CreateModelContext context) { }
protected virtual void GetEditors(GetModelEditorsContext context) {
}
protected virtual void GetEditors(GetModelEditorsContext context) {}
protected virtual void UpdateEditors(UpdateModelContext context) {
}
protected virtual void UpdateEditors(UpdateModelContext context) {}
}
}

View File

@@ -2,13 +2,20 @@ using Orchard.Data;
using Orchard.Models.Records;
namespace Orchard.Models.Driver {
public abstract class ModelDriverWithRecord<TRecord> : ModelDriver where TRecord : ModelPartRecord {
public abstract class ModelDriverWithRecord<TRecord> : ModelDriver where TRecord : ModelPartRecord, new() {
private readonly IRepository<TRecord> _repository;
public ModelDriverWithRecord(IRepository<TRecord> repository) {
protected ModelDriverWithRecord(IRepository<TRecord> repository) {
_repository = repository;
}
protected override void Newed(NewedModelContext context) {
var instance = context.Instance.As<ModelPartWithRecord<TRecord>>();
if (instance != null && instance.Record == null) {
instance.Record = new TRecord();
}
}
protected override void Create(CreateModelContext context) {
var instance = context.Instance.As<ModelPartWithRecord<TRecord>>();
if (instance != null && instance.Record != null) {

View File

@@ -3,4 +3,8 @@ namespace Orchard.Models.Driver {
public string ModelType { get; set; }
public ModelBuilder Builder { get; set; }
}
public class NewedModelContext {
public string ModelType { get; set; }
public IModel Instance { get; set; }
}
}

View File

@@ -1,5 +1,4 @@
using System.Collections.Generic;
using System.Web.Mvc;
using Orchard.Models.Driver;
using Orchard.UI.Models;