Doing some more refinement on the record/handler relationship

--HG--
extra : convert_revision : svn%3A5ff7c347-ad56-4c35-b696-ccb81de16e03/trunk%4041358
This commit is contained in:
loudej
2009-11-19 06:06:51 +00:00
parent baba3c3eca
commit f215b13393
24 changed files with 105 additions and 110 deletions

View File

@@ -4,10 +4,10 @@ using Orchard.Models.Driver;
using Orchard.Models.Records;
namespace Orchard.Tests.Models.Stubs {
public class Gamma : ContentItemPartWithRecord<GammaRecord> {
public class Gamma : ContentPartForRecord<GammaRecord> {
}
public class GammaRecord : ContentPartRecordBase {
public class GammaRecord : ContentPartRecord {
public virtual string Frap { get; set; }
}

View File

@@ -3,7 +3,7 @@ using Orchard.Models;
using Orchard.Security;
namespace Orchard.Core.Common.Models {
public class CommonPart : ContentItemPartWithRecord<CommonRecord> {
public class CommonPart : ContentPartForRecord<CommonRecord> {
public IUser Owner { get; set; }
}
}

View File

@@ -2,6 +2,6 @@ using Orchard.Core.Common.Records;
using Orchard.Models;
namespace Orchard.Core.Common.Models {
public class RoutablePart : ContentItemPartWithRecord<RoutableRecord> {
public class RoutablePart : ContentPartForRecord<RoutableRecord> {
}
}

View File

@@ -2,7 +2,7 @@
using Orchard.Models.Records;
namespace Orchard.Core.Common.Records {
public class CommonRecord : ContentPartRecordBase {
public class CommonRecord : ContentPartRecord {
public virtual int OwnerId { get; set; }
public virtual DateTime? CreatedUtc { get; set; }
public virtual DateTime? ModifiedUtc { get; set; }

View File

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

View File

@@ -3,7 +3,7 @@ using Orchard.Models;
using Orchard.Settings;
namespace Orchard.Core.Settings.Models {
public sealed class SiteSettings : ContentItemPartWithRecord<SiteSettingsRecord>, ISite {
public sealed class SiteSettings : ContentPartForRecord<SiteSettingsRecord>, ISite {
public string SiteName {
get { return Record.SiteName; }
set { Record.SiteName = value; }

View File

@@ -1,7 +1,7 @@
using Orchard.Models.Records;
namespace Orchard.Core.Settings.Records {
public class SiteSettingsRecord : ContentPartRecordBase {
public class SiteSettingsRecord : ContentPartRecord {
public virtual string SiteUrl { get; set; }
public virtual string SiteName { get; set; }
public virtual string SuperUser { get; set; }

View File

@@ -5,10 +5,10 @@ using Orchard.Models.Records;
using Orchard.UI.Models;
namespace Orchard.Media.Models {
public class MediaSettings : ContentItemPartWithRecord<MediaSettingsRecord> {
public class MediaSettings : ContentPartForRecord<MediaSettingsRecord> {
}
public class MediaSettingsRecord : ContentPartRecordBase {
public class MediaSettingsRecord : ContentPartRecord {
public virtual string RootMediaFolder { get; set; }
}

View File

@@ -2,7 +2,7 @@
using Orchard.Security;
namespace Orchard.Users.Models {
public sealed class User : ContentItemPartWithRecord<UserRecord>, IUser {
public sealed class User : ContentPartForRecord<UserRecord>, IUser {
public int Id {
get { return ContentItem.Id; }
}

View File

@@ -2,7 +2,7 @@ using System.Web.Security;
using Orchard.Models.Records;
namespace Orchard.Users.Models {
public class UserRecord : ContentPartRecordBase {
public class UserRecord : ContentPartRecord {
public virtual string UserName { get; set; }
public virtual string Email { get; set; }

View File

@@ -1,4 +1,5 @@
<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<Orchard.Users.ViewModels.UsersIndexViewModel>" %>
<%@ Import Namespace="Orchard.Models"%>
<%@ Import Namespace="Orchard.Security" %>
<%@ Import Namespace="Orchard.Mvc.Html" %>
@@ -38,10 +39,10 @@
<% foreach (var row in Model.Rows) { %>
<tr>
<td>
<%=Html.Encode(row.User.As<IUser>().UserName) %>
<%=Html.Encode(row.User.UserName) %>
</td>
<td>
<%=Html.Encode(row.User.As<IUser>().Email) %>
<%=Html.Encode(row.User.Email) %>
</td>
<td>
<%=Html.ActionLink("Edit", "Edit", new { row.User.Id })%>

View File

@@ -1,46 +0,0 @@
using System.ComponentModel.DataAnnotations;
using Orchard.Data;
using Orchard.Models;
using Orchard.Models.Driver;
using Orchard.Models.Records;
using Orchard.UI.Models;
namespace Orchard.Wikis.Models {
public class WikiSettings : ContentItemPartWithRecord<WikiSettingsRecord> {
}
public class WikiSettingsRecord : ContentPartRecordBase {
public virtual bool AllowAnonymousEdits { get; set; }
[Required]
public virtual string WikiEditTheme { get; set; }
}
public class WikiSettingsHandler : ContentHandler {
public WikiSettingsHandler(IRepository<WikiSettingsRecord> repository) {
Filters.Add(new ActivatingFilter<WikiSettings>("site"));
Filters.Add(new StorageFilterForRecord<WikiSettingsRecord>(repository) { AutomaticallyCreateMissingRecord = true });
//add to user... just for fun
Filters.Add(new ActivatingFilter<WikiSettings>("user"));
}
protected override void GetEditors(GetContentEditorsContext context) {
var model = context.ContentItem.As<WikiSettings>();
if (model == null)
return;
context.Editors.Add(ModelTemplate.For(model.Record, "WikiSettings"));
}
protected override void UpdateEditors(UpdateContentContext context) {
var model = context.ContentItem.As<WikiSettings>();
if (model == null)
return;
context.Updater.TryUpdateModel(model.Record, "WikiSettings", null, null);
context.Editors.Add(ModelTemplate.For(model.Record, "WikiSettings"));
}
}
}

View File

@@ -0,0 +1,30 @@
using Orchard.Data;
using Orchard.Models;
using Orchard.Models.Driver;
using Orchard.UI.Models;
namespace Orchard.Wikis.Models {
public class WikiSettingsHandler : ContentHandler {
public WikiSettingsHandler(IRepository<WikiSettingsRecord> repository) {
Filters.Add(new ActivatingFilter<ContentPartForRecord<WikiSettingsRecord>>("site"));
Filters.Add(new StorageFilterForRecord<WikiSettingsRecord>(repository) { AutomaticallyCreateMissingRecord = true });
}
protected override void GetEditors(GetContentEditorsContext context) {
var part = context.ContentItem.As<ContentPartForRecord<WikiSettingsRecord>>();
if (part == null)
return;
context.Editors.Add(ModelTemplate.For(part.Record, "WikiSettings"));
}
protected override void UpdateEditors(UpdateContentContext context) {
var part = context.ContentItem.As<ContentPartForRecord<WikiSettingsRecord>>();
if (part == null)
return;
context.Updater.TryUpdateModel(part.Record, "WikiSettings", null, null);
context.Editors.Add(ModelTemplate.For(part.Record, "WikiSettings"));
}
}
}

View File

@@ -0,0 +1,11 @@
using System.ComponentModel.DataAnnotations;
using Orchard.Models.Records;
namespace Orchard.Wikis.Models {
public class WikiSettingsRecord : ContentPartRecord {
public virtual bool AllowAnonymousEdits { get; set; }
[Required]
public virtual string WikiEditTheme { get; set; }
}
}

View File

@@ -64,7 +64,8 @@
<Compile Include="AdminMenu.cs" />
<Compile Include="Controllers\AdminController.cs" />
<Compile Include="Models\WikiPageHandler.cs" />
<Compile Include="Models\WikiSettings.cs" />
<Compile Include="Models\WikiSettingsHandler.cs" />
<Compile Include="Models\WikiSettingsRecord.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>

View File

@@ -1,4 +1,5 @@
using System;
using System.Linq;
using System.Reflection;
using System.Threading;
using System.Web;
@@ -62,6 +63,7 @@ namespace Orchard.Data {
private static bool IsRecordType(Type type) {
return (type.Namespace.EndsWith(".Models") || type.Namespace.EndsWith(".Records")) &&
type.GetProperty("Id") != null &&
type.GetProperty("Id").GetAccessors().All(x => x.IsVirtual) &&
!type.IsSealed &&
!type.IsAbstract &&
!typeof(IContentItemPart).IsAssignableFrom(type);

View File

@@ -0,0 +1,29 @@
using System.Collections.Generic;
using System.Linq;
namespace Orchard.Models {
public class ContentItem {
public ContentItem() {
_parts = new List<IContentItemPart>();
}
private readonly IList<IContentItemPart> _parts;
public int Id { get; set; }
public string ContentType { get; set; }
public bool Has<TPart>() {
return _parts.Any(part => part is TPart);
}
public TPart Get<TPart>() {
return _parts.OfType<TPart>().FirstOrDefault();
}
public void Weld(IContentItemPart part) {
part.ContentItem = this;
_parts.Add(part);
}
}
}

View File

@@ -1,33 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace Orchard.Models {
public class ContentItem {
public ContentItem() {
_parts = new List<IContentItemPart>();
}
private readonly IList<IContentItemPart> _parts;
public int Id { get; set; }
public string ContentType { get; set; }
public bool Has<TPart>() {
return _parts.Any(part => part is TPart);
}
public TPart Get<TPart>() {
return _parts.OfType<TPart>().FirstOrDefault();
}
public void Weld(IContentItemPart part) {
part.ContentItem = this;
_parts.Add(part);
}
}
public abstract class ContentItemPart : IContentItemPart {
public ContentItem ContentItem { get; set; }
}

View File

@@ -1,5 +0,0 @@
namespace Orchard.Models {
public abstract class ContentItemPartWithRecord<TRecord> : ContentItemPart {
public TRecord Record { get; set; }
}
}

View File

@@ -0,0 +1,5 @@
namespace Orchard.Models {
public class ContentPartForRecord<TRecord> : ContentItemPart {
public TRecord Record { get; set; }
}
}

View File

@@ -2,7 +2,7 @@ using Orchard.Data;
using Orchard.Models.Records;
namespace Orchard.Models.Driver {
public class StorageFilterForRecord<TRecord> : StorageFilterBase<ContentItemPartWithRecord<TRecord>> where TRecord : ContentPartRecordBase,new() {
public class StorageFilterForRecord<TRecord> : StorageFilterBase<ContentPartForRecord<TRecord>> where TRecord : ContentPartRecord,new() {
private readonly IRepository<TRecord> _repository;
public StorageFilterForRecord(IRepository<TRecord> repository) {
@@ -11,16 +11,16 @@ namespace Orchard.Models.Driver {
public bool AutomaticallyCreateMissingRecord { get; set; }
protected override void Activated(ActivatedContentContext context, ContentItemPartWithRecord<TRecord> instance) {
protected override void Activated(ActivatedContentContext context, ContentPartForRecord<TRecord> instance) {
instance.Record = new TRecord();
}
protected override void Creating(CreateContentContext context, ContentItemPartWithRecord<TRecord> instance) {
protected override void Creating(CreateContentContext context, ContentPartForRecord<TRecord> instance) {
instance.Record.ContentItem = context.ContentItemRecord;
_repository.Create(instance.Record);
}
protected override void Loading(LoadContentContext context, ContentItemPartWithRecord<TRecord> instance) {
protected override void Loading(LoadContentContext context, ContentPartForRecord<TRecord> instance) {
instance.Record = _repository.Get(instance.ContentItem.Id);
if (instance.Record == null && AutomaticallyCreateMissingRecord) {
instance.Record = new TRecord {ContentItem = context.ContentItemRecord};

View File

@@ -1,4 +0,0 @@
using System;
namespace Orchard.Models {
}

View File

@@ -4,18 +4,18 @@ using FluentNHibernate.Automapping;
using FluentNHibernate.Automapping.Alterations;
namespace Orchard.Models.Records {
public abstract class ContentPartRecordBase {
public abstract class ContentPartRecord {
public virtual int Id { get; set; }
public virtual ContentItemRecord ContentItem { get; set; }
}
public class ModelPartRecordAlteration : IAutoMappingAlteration {
public class ContentPartRecordAlteration : IAutoMappingAlteration {
public void Alter(AutoPersistenceModel model) {
model.OverrideAll(mapping => {
var genericArguments = mapping.GetType().GetGenericArguments();
if (!genericArguments.Single().IsSubclassOf(typeof(ContentPartRecordBase))) {
if (!genericArguments.Single().IsSubclassOf(typeof(ContentPartRecord))) {
return;
}
@@ -30,7 +30,7 @@ namespace Orchard.Models.Records {
void Override(object mapping);
}
class Alteration<T> : IAlteration where T : ContentPartRecordBase {
class Alteration<T> : IAlteration where T : ContentPartRecord {
public void Override(object o) {
var mapping = (AutoMapping<T>)o;
mapping.Id(x => x.Id).GeneratedBy.Foreign("ContentItem");

View File

@@ -124,6 +124,7 @@
<Compile Include="Localization\Localizer.cs" />
<Compile Include="Localization\LocalizedString.cs" />
<Compile Include="Localization\NullLocalizer.cs" />
<Compile Include="Models\ContentItem.cs" />
<Compile Include="Models\Driver\ActivatedContentContext.cs" />
<Compile Include="Models\Driver\ActivatingFilter.cs" />
<Compile Include="Models\Driver\IContentActivatingFilter.cs" />
@@ -153,9 +154,8 @@
<Compile Include="Models\ContentExtensions.cs" />
<Compile Include="Models\ContentItemPart.cs" />
<Compile Include="Models\IContentItemPart.cs" />
<Compile Include="Models\ContentItemPartWithRecord.cs" />
<Compile Include="Models\ModelRoot.cs" />
<Compile Include="Models\Records\ContentPartRecordBase.cs" />
<Compile Include="Models\ContentPartForRecord.cs" />
<Compile Include="Models\Records\ContentPartRecord.cs" />
<Compile Include="Models\Records\ContentTypeRecord.cs" />
<Compile Include="Models\Records\ContentItemRecord.cs" />
<Compile Include="Models\Driver\UpdateContentContext.cs" />