mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-15 03:25:23 +08:00
Content manager assigning values to definition properties
DefaultContentManager now takes a dependency on IContentDefinitionManager ContentItem.TypeDefinition assigned to ContentTypeDefinition instance when creating ContentPart.TypePartDefinition assigned to ContentTypeDefinition.Part instance as added Empty definition instances are created as code-only types and parts are created --HG-- branch : dev
This commit is contained in:
@@ -6,6 +6,7 @@ using JetBrains.Annotations;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using Orchard.ContentManagement.Aspects;
|
||||
using Orchard.ContentManagement.MetaData;
|
||||
using Orchard.Core.Common;
|
||||
using Orchard.Core.Common.Handlers;
|
||||
using Orchard.Core.Common.Models;
|
||||
@@ -25,6 +26,7 @@ namespace Orchard.Core.Tests.Common.Providers {
|
||||
private Mock<IAuthenticationService> _authn;
|
||||
private Mock<IAuthorizationService> _authz;
|
||||
private Mock<IMembershipService> _membership;
|
||||
private Mock<IContentDefinitionManager> _contentDefinitionManager;
|
||||
|
||||
public override void Register(ContainerBuilder builder) {
|
||||
builder.RegisterType<DefaultContentManager>().As<IContentManager>();
|
||||
@@ -35,11 +37,12 @@ namespace Orchard.Core.Tests.Common.Providers {
|
||||
_authn = new Mock<IAuthenticationService>();
|
||||
_authz = new Mock<IAuthorizationService>();
|
||||
_membership = new Mock<IMembershipService>();
|
||||
_contentDefinitionManager = new Mock<IContentDefinitionManager>();
|
||||
|
||||
builder.RegisterInstance(_authn.Object);
|
||||
builder.RegisterInstance(_authz.Object);
|
||||
builder.RegisterInstance(_membership.Object);
|
||||
|
||||
builder.RegisterInstance(_contentDefinitionManager.Object);
|
||||
}
|
||||
|
||||
protected override IEnumerable<Type> DatabaseTypes {
|
||||
|
@@ -2,10 +2,12 @@
|
||||
using System.Collections.Generic;
|
||||
using Autofac;
|
||||
using JetBrains.Annotations;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.Drivers;
|
||||
using Orchard.ContentManagement.Handlers;
|
||||
using Orchard.ContentManagement.MetaData;
|
||||
using Orchard.ContentManagement.Records;
|
||||
using Orchard.Core.Common.Models;
|
||||
using Orchard.Core.Common.Services;
|
||||
@@ -27,6 +29,7 @@ namespace Orchard.Core.Tests.Common.Services {
|
||||
public override void Register(ContainerBuilder builder) {
|
||||
builder.RegisterType<DefaultContentManager>().As<IContentManager>();
|
||||
builder.RegisterType<DefaultContentManagerSession>().As<IContentManagerSession>();
|
||||
builder.RegisterInstance(new Mock<IContentDefinitionManager>().Object);
|
||||
|
||||
builder.RegisterType<ThingHandler>().As<IContentHandler>();
|
||||
builder.RegisterType<StuffHandler>().As<IContentHandler>();
|
||||
|
@@ -9,6 +9,8 @@ using Moq;
|
||||
using NUnit.Framework;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.Handlers;
|
||||
using Orchard.ContentManagement.MetaData.Builders;
|
||||
using Orchard.ContentManagement.MetaData.Models;
|
||||
using Orchard.Core.Common.Models;
|
||||
using Orchard.Core.Feeds;
|
||||
using Orchard.Core.Feeds.Controllers;
|
||||
@@ -145,7 +147,7 @@ namespace Orchard.Core.Tests.Feeds.Controllers {
|
||||
[Test]
|
||||
public void CorePartValuesAreExtracted() {
|
||||
var clock = new StubClock();
|
||||
var hello = new ContentItemBuilder("hello")
|
||||
var hello = new ContentItemBuilder(new ContentTypeDefinitionBuilder().Named("hello").Build())
|
||||
.Weld<CommonAspect>()
|
||||
.Weld<RoutableAspect>()
|
||||
.Weld<BodyAspect>()
|
||||
|
@@ -4,6 +4,7 @@ using Autofac;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.MetaData;
|
||||
using Orchard.ContentManagement.Records;
|
||||
using Orchard.Core.Scheduling.Models;
|
||||
using Orchard.Core.Scheduling.Services;
|
||||
@@ -29,6 +30,7 @@ namespace Orchard.Core.Tests.Scheduling {
|
||||
builder.RegisterInstance(new Mock<IOrchardServices>().Object);
|
||||
builder.RegisterType<DefaultContentManager>().As<IContentManager>();
|
||||
builder.RegisterType<DefaultContentManagerSession>().As<IContentManagerSession>();
|
||||
builder.RegisterInstance(new Mock<IContentDefinitionManager>().Object);
|
||||
|
||||
builder.RegisterType<ScheduledTaskExecutor>().As<IBackgroundTask>().Named("ScheduledTaskExecutor", typeof(IBackgroundTask));
|
||||
builder.RegisterInstance(_handler).As<IScheduledTaskHandler>();
|
||||
|
@@ -5,6 +5,7 @@ using Autofac;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.MetaData;
|
||||
using Orchard.ContentManagement.Records;
|
||||
using Orchard.Core.Scheduling.Models;
|
||||
using Orchard.Core.Scheduling.Services;
|
||||
@@ -33,6 +34,7 @@ namespace Orchard.Core.Tests.Scheduling {
|
||||
builder.RegisterInstance(_mockServices.Object);
|
||||
builder.RegisterType<DefaultContentManager>().As<IContentManager>();
|
||||
builder.RegisterType<DefaultContentManagerSession>().As<IContentManagerSession>();
|
||||
builder.RegisterInstance(new Mock<IContentDefinitionManager>().Object);
|
||||
|
||||
builder.RegisterType<ScheduledTaskManager>().As<IScheduledTaskManager>();
|
||||
}
|
||||
|
@@ -1,7 +1,9 @@
|
||||
using System.Linq;
|
||||
using Autofac;
|
||||
using Moq;
|
||||
using NHibernate;
|
||||
using NUnit.Framework;
|
||||
using Orchard.ContentManagement.MetaData;
|
||||
using Orchard.Data;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.Handlers;
|
||||
@@ -44,6 +46,7 @@ namespace Orchard.Tests.ContentManagement {
|
||||
builder.RegisterModule(new ContentModule());
|
||||
builder.RegisterType<DefaultContentManager>().As<IContentManager>().SingleInstance();
|
||||
builder.RegisterType<DefaultContentManagerSession>().As<IContentManagerSession>();
|
||||
builder.RegisterInstance(new Mock<IContentDefinitionManager>().Object);
|
||||
|
||||
builder.RegisterType<AlphaHandler>().As<IContentHandler>();
|
||||
builder.RegisterType<BetaHandler>().As<IContentHandler>();
|
||||
|
@@ -2,8 +2,11 @@
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using Autofac;
|
||||
using Moq;
|
||||
using NHibernate;
|
||||
using NUnit.Framework;
|
||||
using Orchard.ContentManagement.MetaData;
|
||||
using Orchard.ContentManagement.MetaData.Builders;
|
||||
using Orchard.Data;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.Handlers;
|
||||
@@ -18,6 +21,7 @@ namespace Orchard.Tests.ContentManagement {
|
||||
private IContentManager _manager;
|
||||
private ISessionFactory _sessionFactory;
|
||||
private ISession _session;
|
||||
private Mock<IContentDefinitionManager> _contentDefinitionManager;
|
||||
|
||||
[TestFixtureSetUp]
|
||||
public void InitFixture() {
|
||||
@@ -39,10 +43,12 @@ namespace Orchard.Tests.ContentManagement {
|
||||
|
||||
[SetUp]
|
||||
public void Init() {
|
||||
_contentDefinitionManager = new Mock<IContentDefinitionManager>();
|
||||
|
||||
var builder = new ContainerBuilder();
|
||||
//builder.RegisterModule(new ImplicitCollectionSupportModule());
|
||||
builder.RegisterType<DefaultContentManager>().As<IContentManager>();
|
||||
builder.RegisterType<DefaultContentManagerSession>().As<IContentManagerSession>();
|
||||
builder.RegisterInstance(_contentDefinitionManager.Object);
|
||||
|
||||
builder.RegisterType<AlphaHandler>().As<IContentHandler>();
|
||||
builder.RegisterType<BetaHandler>().As<IContentHandler>();
|
||||
@@ -459,6 +465,40 @@ namespace Orchard.Tests.ContentManagement {
|
||||
Assert.That(gammas[3].Version, Is.EqualTo(4));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void EmptyTypeDefinitionShouldBeCreatedIfNotAlreadyDefined() {
|
||||
var contentItem = _manager.New("no-such-type");
|
||||
Assert.That(contentItem.ContentType, Is.EqualTo("no-such-type"));
|
||||
Assert.That(contentItem.TypeDefinition, Is.Not.Null);
|
||||
Assert.That(contentItem.TypeDefinition.Name, Is.EqualTo("no-such-type"));
|
||||
Assert.That(contentItem.TypeDefinition.Settings.Count(), Is.EqualTo(0));
|
||||
Assert.That(contentItem.TypeDefinition.Parts.Count(), Is.EqualTo(0));
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void ExistingTypeAndPartDefinitionShouldBeUsed() {
|
||||
var alphaType = new ContentTypeDefinitionBuilder()
|
||||
.Named("alpha")
|
||||
.WithSetting("x", "1")
|
||||
.WithPart("foo")
|
||||
.WithPart("Flavored", part => part.WithSetting("spin", "clockwise"))
|
||||
.Build();
|
||||
|
||||
_contentDefinitionManager
|
||||
.Setup(x => x.GetTypeDefinition("alpha"))
|
||||
.Returns(alphaType);
|
||||
|
||||
var contentItem = _manager.New("alpha");
|
||||
Assert.That(contentItem.ContentType, Is.EqualTo("alpha"));
|
||||
Assert.That(contentItem.TypeDefinition, Is.Not.Null);
|
||||
Assert.That(contentItem.TypeDefinition, Is.SameAs(alphaType));
|
||||
|
||||
var flavored = contentItem.As<Flavored>();
|
||||
Assert.That(flavored, Is.Not.Null);
|
||||
Assert.That(flavored.TypePartDefinition, Is.Not.Null);
|
||||
Assert.That(flavored.TypePartDefinition.Settings["spin"], Is.EqualTo("clockwise"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -1,6 +1,7 @@
|
||||
using NUnit.Framework;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.Handlers;
|
||||
using Orchard.ContentManagement.MetaData.Builders;
|
||||
|
||||
namespace Orchard.Tests.ContentManagement.Handlers {
|
||||
|
||||
@@ -22,7 +23,7 @@ namespace Orchard.Tests.ContentManagement.Handlers {
|
||||
public void PartShouldBeAddedBasedOnSimplePredicate() {
|
||||
var modelDriver = new TestModelHandler();
|
||||
|
||||
var builder = new ContentItemBuilder("testing");
|
||||
var builder = new ContentItemBuilder(new ContentTypeDefinitionBuilder().Named("testing").Build());
|
||||
((IContentHandler)modelDriver).Activating(new ActivatingContentContext { Builder = builder, ContentType = "testing" });
|
||||
var model = builder.Build();
|
||||
Assert.That(model.Is<TestModelPart>(), Is.True);
|
||||
|
@@ -5,6 +5,7 @@ using System.Text;
|
||||
using NUnit.Framework;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.Handlers;
|
||||
using Orchard.ContentManagement.MetaData.Builders;
|
||||
using Orchard.Tests.ContentManagement.Models;
|
||||
|
||||
namespace Orchard.Tests.ContentManagement.Handlers {
|
||||
@@ -12,21 +13,21 @@ namespace Orchard.Tests.ContentManagement.Handlers {
|
||||
public class ModelBuilderTests {
|
||||
[Test]
|
||||
public void BuilderShouldReturnWorkingModelWithTypeAndId() {
|
||||
var builder = new ContentItemBuilder("foo");
|
||||
var builder = new ContentItemBuilder(new ContentTypeDefinitionBuilder().Named("foo").Build());
|
||||
var model = builder.Build();
|
||||
Assert.That(model.ContentType, Is.EqualTo("foo"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IdShouldDefaultToZero() {
|
||||
var builder = new ContentItemBuilder("foo");
|
||||
var builder = new ContentItemBuilder(new ContentTypeDefinitionBuilder().Named("foo").Build());
|
||||
var model = builder.Build();
|
||||
Assert.That(model.Id, Is.EqualTo(0));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WeldShouldAddPartToModel() {
|
||||
var builder = new ContentItemBuilder("foo");
|
||||
var builder = new ContentItemBuilder(new ContentTypeDefinitionBuilder().Named("foo").Build());
|
||||
builder.Weld<Alpha>();
|
||||
var model = builder.Build();
|
||||
|
||||
|
@@ -24,6 +24,7 @@ namespace Orchard.Core.Routable.Controllers {
|
||||
if (string.IsNullOrEmpty(matchedPath)) {
|
||||
throw new ApplicationException("404 - should not have passed path constraint");
|
||||
}
|
||||
|
||||
var hits = _contentManager
|
||||
.Query<IsRoutable, RoutableRecord>(VersionOptions.Published)
|
||||
.Where(r => r.Path == matchedPath)
|
||||
|
@@ -1,12 +1,14 @@
|
||||
using System.Collections.Generic;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.Handlers;
|
||||
using Orchard.ContentManagement.MetaData.Builders;
|
||||
using Orchard.Security;
|
||||
|
||||
namespace Orchard.Roles.Models {
|
||||
public static class UserSimulation {
|
||||
public static IUser Create(string role) {
|
||||
var simulation = new ContentItemBuilder("user")
|
||||
var simulationType = new ContentTypeDefinitionBuilder().Named("user").Build();
|
||||
var simulation = new ContentItemBuilder(simulationType)
|
||||
.Weld<SimulatedUser>()
|
||||
.Weld<SimulatedUserRoles>()
|
||||
.Build();
|
||||
|
@@ -7,6 +7,7 @@ using Orchard.Commands;
|
||||
using Orchard.Commands.Builtin;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.Handlers;
|
||||
using Orchard.ContentManagement.MetaData.Builders;
|
||||
using Orchard.Data.Builders;
|
||||
using Orchard.Environment.Extensions;
|
||||
using Orchard.Localization;
|
||||
@@ -90,7 +91,8 @@ namespace Orchard.Setup {
|
||||
|
||||
class SafeModeSiteService : ISiteService {
|
||||
public ISite GetSiteSettings() {
|
||||
var site = new ContentItemBuilder("site")
|
||||
var siteType = new ContentTypeDefinitionBuilder().Named("site").Build();
|
||||
var site = new ContentItemBuilder(siteType)
|
||||
.Weld<SafeModeSite>()
|
||||
.Build();
|
||||
|
||||
|
@@ -4,9 +4,9 @@ using Orchard.ContentManagement.Utilities;
|
||||
namespace Orchard.ContentManagement {
|
||||
public abstract class ContentPart : IContent {
|
||||
public virtual ContentItem ContentItem { get; set; }
|
||||
public ContentTypeDefinition TypeDefinition { get; set; }
|
||||
public ContentTypeDefinition TypeDefinition { get { return ContentItem.TypeDefinition; } }
|
||||
public ContentTypeDefinition.Part TypePartDefinition { get; set; }
|
||||
public ContentPartDefinition PartDefinition { get; set; }
|
||||
public ContentPartDefinition PartDefinition { get { return TypePartDefinition.PartDefinition; } }
|
||||
}
|
||||
|
||||
public class ContentPart<TRecord> : ContentPart {
|
||||
|
@@ -3,6 +3,9 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Autofac;
|
||||
using Orchard.ContentManagement.Handlers;
|
||||
using Orchard.ContentManagement.MetaData;
|
||||
using Orchard.ContentManagement.MetaData.Builders;
|
||||
using Orchard.ContentManagement.MetaData.Models;
|
||||
using Orchard.ContentManagement.Records;
|
||||
using Orchard.Data;
|
||||
using Orchard.Mvc.ViewModels;
|
||||
@@ -13,6 +16,7 @@ namespace Orchard.ContentManagement {
|
||||
private readonly IRepository<ContentTypeRecord> _contentTypeRepository;
|
||||
private readonly IRepository<ContentItemRecord> _contentItemRepository;
|
||||
private readonly IRepository<ContentItemVersionRecord> _contentItemVersionRepository;
|
||||
private readonly IContentDefinitionManager _contentDefinitionManager;
|
||||
private readonly Func<IContentManagerSession> _contentManagerSession;
|
||||
|
||||
public DefaultContentManager(
|
||||
@@ -20,11 +24,13 @@ namespace Orchard.ContentManagement {
|
||||
IRepository<ContentTypeRecord> contentTypeRepository,
|
||||
IRepository<ContentItemRecord> contentItemRepository,
|
||||
IRepository<ContentItemVersionRecord> contentItemVersionRepository,
|
||||
IContentDefinitionManager contentDefinitionManager,
|
||||
Func<IContentManagerSession> contentManagerSession) {
|
||||
_context = context;
|
||||
_contentTypeRepository = contentTypeRepository;
|
||||
_contentItemRepository = contentItemRepository;
|
||||
_contentItemVersionRepository = contentItemVersionRepository;
|
||||
_contentDefinitionManager = contentDefinitionManager;
|
||||
_contentManagerSession = contentManagerSession;
|
||||
}
|
||||
|
||||
@@ -44,11 +50,16 @@ namespace Orchard.ContentManagement {
|
||||
}
|
||||
|
||||
public virtual ContentItem New(string contentType) {
|
||||
var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(contentType);
|
||||
if (contentTypeDefinition == null) {
|
||||
contentTypeDefinition = new ContentTypeDefinitionBuilder().Named(contentType).Build();
|
||||
}
|
||||
|
||||
// create a new kernel for the model instance
|
||||
var context = new ActivatingContentContext {
|
||||
ContentType = contentType,
|
||||
Builder = new ContentItemBuilder(contentType)
|
||||
ContentType = contentTypeDefinition.Name,
|
||||
Definition = contentTypeDefinition,
|
||||
Builder = new ContentItemBuilder(contentTypeDefinition)
|
||||
};
|
||||
|
||||
// invoke handlers to weld aspects onto kernel
|
||||
|
@@ -52,11 +52,12 @@ namespace Orchard.ContentManagement.Drivers {
|
||||
return new CombinedResult(results);
|
||||
}
|
||||
|
||||
public IEnumerable<ContentPartInfo> GetPartInfo()
|
||||
{
|
||||
var contentPartInfo = new List<ContentPartInfo>() {
|
||||
new ContentPartInfo()
|
||||
{PartName = typeof(TContent).Name,Factory = () => new TContent()}
|
||||
public IEnumerable<ContentPartInfo> GetPartInfo() {
|
||||
var contentPartInfo = new[] {
|
||||
new ContentPartInfo {
|
||||
PartName = typeof (TContent).Name,
|
||||
Factory = typePartDefinition => new TContent {TypePartDefinition = typePartDefinition}
|
||||
}
|
||||
};
|
||||
|
||||
return contentPartInfo;
|
||||
|
@@ -1,6 +1,9 @@
|
||||
using Orchard.ContentManagement.MetaData.Models;
|
||||
|
||||
namespace Orchard.ContentManagement.Handlers {
|
||||
public class ActivatingContentContext {
|
||||
public string ContentType { get; set; }
|
||||
public ContentTypeDefinition Definition { get; set; }
|
||||
public ContentItemBuilder Builder { get; set; }
|
||||
}
|
||||
}
|
||||
|
@@ -1,9 +1,18 @@
|
||||
namespace Orchard.ContentManagement.Handlers {
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Orchard.ContentManagement.MetaData.Models;
|
||||
|
||||
namespace Orchard.ContentManagement.Handlers {
|
||||
public class ContentItemBuilder {
|
||||
private readonly ContentTypeDefinition _definition;
|
||||
private readonly ContentItem _item;
|
||||
|
||||
public ContentItemBuilder(string contentType) {
|
||||
_item = new ContentItem { ContentType = contentType };
|
||||
public ContentItemBuilder(ContentTypeDefinition definition) {
|
||||
_definition = definition;
|
||||
_item = new ContentItem {
|
||||
ContentType = definition.Name,
|
||||
TypeDefinition = definition
|
||||
};
|
||||
}
|
||||
|
||||
public ContentItem Build() {
|
||||
@@ -11,7 +20,18 @@
|
||||
}
|
||||
|
||||
public ContentItemBuilder Weld<TPart>() where TPart : ContentPart, new() {
|
||||
var part = new TPart();
|
||||
var partName = typeof(TPart).Name;
|
||||
|
||||
var typePartDefinition = _definition.Parts.FirstOrDefault(p => p.PartDefinition.Name == partName);
|
||||
if (typePartDefinition == null) {
|
||||
typePartDefinition = new ContentTypeDefinition.Part(
|
||||
new ContentPartDefinition(partName),
|
||||
new Dictionary<string, string>());
|
||||
}
|
||||
|
||||
var part = new TPart {
|
||||
TypePartDefinition = typePartDefinition
|
||||
};
|
||||
_item.Weld(part);
|
||||
return this;
|
||||
}
|
||||
@@ -20,6 +40,5 @@
|
||||
_item.Weld(contentPart);
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@@ -14,14 +14,15 @@ namespace Orchard.ContentManagement.MetaData {
|
||||
}
|
||||
|
||||
public override void Activating(ActivatingContentContext context) {
|
||||
var contentTypeRecord = _contentDefinitionManager.GetTypeDefinition(context.ContentType);
|
||||
if (contentTypeRecord == null)
|
||||
var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(context.ContentType);
|
||||
if (contentTypeDefinition == null)
|
||||
return;
|
||||
|
||||
foreach (var partInfo in _contentPartDrivers.SelectMany(cpp => cpp.GetPartInfo())) {
|
||||
var partName = partInfo.PartName;
|
||||
if (contentTypeRecord.Parts.Any(p=>p.PartDefinition.Name == partName)) {
|
||||
context.Builder.Weld(partInfo.Factory());
|
||||
var typePartDefinition = contentTypeDefinition.Parts.FirstOrDefault(p => p.PartDefinition.Name == partName);
|
||||
if (typePartDefinition != null) {
|
||||
context.Builder.Weld(partInfo.Factory(typePartDefinition));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,10 +1,9 @@
|
||||
using System;
|
||||
using Orchard.ContentManagement.MetaData.Models;
|
||||
|
||||
namespace Orchard.ContentManagement.MetaData
|
||||
{
|
||||
public class ContentPartInfo
|
||||
{
|
||||
namespace Orchard.ContentManagement.MetaData {
|
||||
public class ContentPartInfo {
|
||||
public string PartName { get; set; }
|
||||
public Func<ContentPart> Factory { get; set; }
|
||||
public Func<ContentTypeDefinition.Part, ContentPart> Factory { get; set; }
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user