DNN搜索引擎研究续 • 如何使自定义模块加入DNN搜索引擎

提纲挈领地,要使DNN的自定义模块加入搜索引擎,有如下3个要点:

1、自定义模块的Controller类要实现ISearchable接口。这个是肯定的。

2、模块定义时一定要填写Controller Class属性。因为搜索引擎的调度执行的时候,会利用反射创建Controller Class,寻找实现ISearchable接口的GetSearchItem方法。

3DNN_DesktopModules表的SupportedFeatures字段,要填3
--------------------------------------------------------------------------------------------------------


      1
、先看如何实现ISearchable接口。

在先前的DNN搜索引擎研究中提到:在DNN的架构中,提供了一个ISearchable的接口,只要实现这个接口的模块,都可以作为搜索的数据源。同样的,你如果想让自己写的模块被搜索引擎收录的话,你就要实现ISearchable接口。

我们来看一下ISearchable接口的内容,该接口位于DotNetNuke/Components/Modules(在解决方案中的路径)下面。

 

 1 None.gif '
 2 None.gif'  DotNetNuke?- http://www.dotnetnuke.com
 3 None.gif'  Copyright (c) 2002-2005
 4 None.gif'  by Perpetual Motion Interactive Systems Inc. ( http://www.perpetualmotion.ca )
 5 None.gif'
 6 None.gif'  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 
 7 None.gif'  documentation files (the "Software"), to deal in the Software without restriction, including without limitation 
 8 None.gif'  the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and 
 9 None.gif'  to permit persons to whom the Software is furnished to do so, subject to the following conditions:
10 None.gif'
11 None.gif'  The above copyright notice and this permission notice shall be included in all copies or substantial portions 
12 None.gif'  of the Software.
13 None.gif'
14 None.gif'  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 
15 None.gif'  TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
16 None.gif'  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 
17 None.gif'  CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
18 None.gif'  DEALINGS IN THE SOFTWARE.
19 None.gif'
20 None.gif
21 None.gif Imports  DotNetNuke.Services.Search
22 None.gif
23 ExpandedBlockStart.gifContractedBlock.gif Namespace DotNetNuke Namespace DotNetNuke.Entities.Modules
24ExpandedSubBlockStart.gifContractedSubBlock.gif    Public Interface ISearchableInterface ISearchable
25ExpandedSubBlockStart.gifContractedSubBlock.gif        Function GetSearchItems()Function GetSearchItems(ByVal ModInfo As ModuleInfo) As SearchItemInfoCollection
26ExpandedSubBlockEnd.gif    End Interface

27ExpandedBlockEnd.gifEnd Namespace

28 None.gif

很简单,该接口只有一个方法声明,GetSearchItems,在搜索引擎执行的时候,DNN会根据此方法获取能够被搜索的模块项目。那么,如何实现该接口呢?我们首先看一下DNN自带的模块是怎么做的,比如Links模块。

 

 1 None.gif          ' '' -----------------------------------------------------------------------------
 2 None.gif          ' '' <summary>
 3 None.gif          ' '' GetSearchItems implements the ISearchable Interface
 4 None.gif          ' '' </summary>
 5 None.gif          ' '' <remarks>
 6 None.gif          ' '' </remarks>
 7 None.gif          ' '' <param name="ModInfo">The ModuleInfo for the module to be Indexed</param>
 8 None.gif          ' '' <history>
 9 None.gif          ' ''        [cnurse]    11/17/2004    documented
10 None.gif          ' '' </history>
11 None.gif          ' '' -----------------------------------------------------------------------------
12 ExpandedBlockStart.gifContractedBlock.gif          Public   Function GetSearchItems() Function GetSearchItems(ByVal ModInfo As Entities.Modules.ModuleInfo) As Services.Search.SearchItemInfoCollection Implements Entities.Modules.ISearchable.GetSearchItems
13InBlock.gif            Dim SearchItemCollection As New SearchItemInfoCollection
14InBlock.gif
15InBlock.gif            Dim Links As ArrayList = GetLinks(ModInfo.ModuleID)
16InBlock.gif
17InBlock.gif            Dim objLink As Object
18InBlock.gif            For Each objLink In Links
19InBlock.gif                Dim SearchItem As SearchItemInfo
20InBlock.gif                With CType(objLink, LinkInfo)
21InBlock.gif                    ' 
22InBlock.gif                    Dim UserId As Integer = Null.NullInteger
23InBlock.gif                    If IsNumeric(.CreatedByUser) Then
24InBlock.gif                        UserId = Integer.Parse(.CreatedByUser)
25InBlock.gif                    End If
26InBlock.gif                    SearchItem = New SearchItemInfo(ModInfo.ModuleTitle & " - " & .Title, .Description, UserId, .CreatedDate, ModInfo.ModuleID, .ItemId.ToString, .Description, "ItemId=" & .ItemId.ToString, Null.NullInteger)
27InBlock.gif                    SearchItemCollection.Add(SearchItem)
28InBlock.gif                End With
29InBlock.gif            Next
30InBlock.gif
31InBlock.gif            Return SearchItemCollection
32ExpandedBlockEnd.gif        End Function

33 None.gif

参照这些代码,我们可以书写自己的GetSearchItems方法了。注意,这个接口的实现是写在模块的Controller类中的。假如你要写一个新闻模块,那么GetSearchItems方法可以书写如下:
  

 1 None.gif          public  DotNetNuke.Services.Search.SearchItemInfoCollection GetSearchItems(DotNetNuke.Entities.Modules.ModuleInfo ModInfo)
 2 ExpandedBlockStart.gifContractedBlock.gif         dot.gif {
 3InBlock.gif            DotNetNuke.Services.Search.SearchItemInfoCollection searchItems = new DotNetNuke.Services.Search.SearchItemInfoCollection();
 4InBlock.gif            ArrayList News = List(ModInfo.ModuleID);
 5InBlock.gif            foreach(NewsInfo news in News)
 6ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
 7InBlock.gif                DotNetNuke.Services.Search.SearchItemInfo item;
 8InBlock.gif                item = new DotNetNuke.Services.Search.SearchItemInfo(ModInfo.ModuleTitle + "-" + news.Title,news.Content,Null.NullInteger,news.CreateDate,ModInfo.ModuleID,news.ItemID.ToString(),news.Content,Null.NullInteger);
 9InBlock.gif                searchItems.Add(item);
10ExpandedSubBlockEnd.gif            }

11InBlock.gif            return searchItems;
12ExpandedBlockEnd.gif        }

13 None.gif


2、在模块管理中进行模块定义时,一定要填写Controller Class属性。

原因是在搜索引擎运行时,会读取模块的此属性,然后使用反射创建Controller Class,检查它是否实现了ISearchable接口。(具体代码在Provider.Search.Index项目的ModuleIndexer类的GetModuleList方法中。)事实上,如果不填写Controller Class,模块也能正常使用,其他地方没有任何异常,所以我就习惯了不填它,结果费了很大劲才搞明白原来是这儿的原因。

3、DNN_DesktopModules表的SupportedFeatures字段,要填3

这个就更诡异了。SupportedFeatures这个字段是什么意思呢?风云在DNN配置-数据库篇中有所解释,该字段表示模块支持的特性。DNN中有个DesktopModuleInfo类,对该属性有所描述:
   

1 ExpandedBlockStart.gif ContractedBlock.gif      Public   Enum DesktopModuleSupportedFeature Enum DesktopModuleSupportedFeature
2InBlock.gif        IsPortable = 1
3InBlock.gif        IsSearchable = 2
4ExpandedBlockEnd.gif    End Enum
None.gif


ModuleInfo类中也有该属性,并且初始值为0。但在模块管理的AddUpdate事件中,根本找不到是在哪儿对该属性赋值的,也就是说,你自定义的模块插入到数据库中,该字段的值肯定是0
    但是,
DNN使用GetSearchModules存储过程获取能够搜索的模块,其中有个where条件是:(DesktopModules.SupportedFeatures & 2 = 2)。因此无论如何你的自定义模块是不会满足这个条件的。去看看LinksText/Html这些DNN自带的能够搜索的模块,发现这个字段是3。那么3代表什么呢?不知道。把自己的模块也改成3,果然就行了。不知道这个是DNN留出的一个扩充接口呢,还是一个Bug
    (我使用的
DNN版本是3.2.2。)

转载于:https://www.cnblogs.com/Athos/archive/2007/03/09/669424.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值