0

交叉邮件: https ://orchard.codeplex.com/discussions/459007

我的第一个问题是,在 2 个不同的模块中为同一 Part 设置 2 个 PartHandler 会产生什么影响?

我陷入了这种困境,因为一旦创建了特定的内容类型,我就必须运行一个方法。为部件连接 OnCreated 很容易,但是,这是我的场景:

  • 模块 A 包含零件和原始处理程序
  • 模块 B 包含方法所在的服务
  • 模块 B 引用了模块 A

因此,我无法在模块 A 中引用模块 B(循环引用)。所以我所做的就是在模块 A 中复制完全相同的 PartHandler 并将其放在模块 B 中。

那会有什么问题吗?

然后是我的第二个问题,我认为这可以解决所有这些问题:我们可以为 Content Item 的默认 Content Part 创建一个 PartHandler 吗?(即所有自定义字段都附加到的部分)

这肯定会让事情变得更容易,因为我可以整合需要在那里运行的东西。

更新 1(为了更好地解释问题 2)

    ContentDefinitionManager.AlterPartDefinition("EventItem",           
      builder => builder                         
                    .WithField("StartDate", cfg => cfg
                        .OfType("DateTimeField")
                        .WithDisplayName("Start Date")
                        .WithSetting("DateTimeFieldSettings.Display", "DateOnly")
                        .WithSetting("DateTimeFieldSettings.Required", "true"))
                    .WithField("StartTime", cfg => cfg
                        .OfType("DateTimeField")
                        .WithDisplayName("Start Time")
                        .WithSetting("DateTimeFieldSettings.Display", "TimeOnly"))
                    .WithField("EndDate", cfg => cfg
                        .OfType("DateTimeField")
                        .WithDisplayName("End Date")
                        .WithSetting("DateTimeFieldSettings.Display", "DateOnly"))
                    .WithField("EndTime", cfg => cfg
                        .OfType("DateTimeField")
                        .WithDisplayName("End Time")
                        .WithSetting("DateTimeFieldSettings.Display", "TimeOnly"))
                    .WithField("Intro", cfg => cfg
                        .OfType("TextField")
                        .WithDisplayName("Intro")
                        .WithSetting("TextFieldSettings.Flavor", "textarea"))

    ContentDefinitionManager.AlterTypeDefinition(
        "EventItem"
        , cfg =>
            cfg
                .DisplayedAs("Event Item")                        
                .WithPart("TitlePart")
                .WithPart("EventItem")
                .WithPart("LocationPart")   
                .WithPart("AutoroutePart", builder => builder
                    .WithSetting("AutorouteSettings.AllowCustomPattern", "true")
                    .WithSetting("AutorouteSettings.AutomaticAdjustmentOnEdit", "false")
                    .WithSetting("AutorouteSettings.PatternDefinitions", "[{Name:'Title', Pattern: 'learn/events/{Content.Slug}', Description: 'learn/events/event-title'}]")
                    .WithSetting("AutorouteSettings.DefaultPatternIndex", "0"))
                .WithPart("CommonPart")
                .Draftable()
                .Creatable()
    );

我说的是为包含所有自定义字段的 EventItem 部分创建一个 ContentHandler。当解决方案的任何类中未定义 EventItemPart 时,我该如何处理?

由于找不到 EventItemPart 类,以下内容将不起作用:

OnCreated<EventItemPart>((context, keynotes) =>
    questionService.SetDefaultQuestions(context.ContentItem));
4

2 回答 2

1

交叉回答:

  1. 无 但是,重复自己几乎总是错误的,尤其是如果它是出于不好的原因。为什么服务和零件在两个不同的模块中?为什么A需要B?循环引用表示紧密耦合。如果紧密耦合是合理的,那么它应该发生在单个模块中。如果不是,那么您需要重新进行设计以将其删除。

  2. 您可以为任何事情创建处理程序,但是您对场景的解释是模糊和抽象的,以提供任何有用的建议。

于 2013-09-25T00:57:23.800 回答
1

交叉回答也是如此。

  1. 伯特兰完全正确。为什么首先需要在 A 中引用 B?如果来自 B 的服务需要 A 而 A 需要这个服务,那么它属于 A(至少是接口 - 合同)。

    您始终可以为您的服务拆分接口和实际实现,将一个与另一个模块放在不同的模块中。如果你的服务的实现需要B的东西,那么把接口放在A中,但在B中实际实现。这样A甚至不需要知道B的存在,但仍然可以通过它的接口使用服务- 这是 IoC 模式和 Orchard 模块化的美妙之处:)

  2. 您可以在处理程序泛型方法中使用ContentPartIContent作为类型参数。这是完全有效的。这样,您就可以插入所有项目的事件,然后执行自定义过滤(基于类型名称、某些字段存在等)。在您的情况下,它可能看起来像:

    OnCreated<ContentPart>((context, part) => 
    {
        if(part.ContentItem.ContentType != "EventItem") return;
        questionService.SetDefaultQuestions(context.ContentItem);
    });
    

更新:无需这样做:.WithPart("EventItem")。这个“假”部分将由框架自动添加。

于 2013-09-25T03:04:29.627 回答