如何使自定义模块加入DNN搜索引擎


转自 http://www.cnblogs.com/Athos/archive/2007/03/09/669424.html

提纲挈领地,要使
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(在解决方案中的路径)下面。

 

  ' DotNetNuke?- http://www.dotnetnuke.com
  '  Copyright (c) 2002-2005
  '  by Perpetual Motion Interactive Systems Inc. ( http://www.perpetualmotion.ca )
  '
  '  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 
  '  documentation files (the "Software"), to deal in the Software without restriction, including without limitation 
  '  the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and 
  '  to permit persons to whom the Software is furnished to do so, subject to the following conditions:
'
'
 The above copyright notice and this permission notice shall be included in all copies or substantial portions 
'
 of the Software.
'
'
 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 
'
 TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
'
 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 
'
 CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
'
 DEALINGS IN THE SOFTWARE.
'

Imports  DotNetNuke.Services.Search

Namespace  DotNetNukeNamespace DotNetNuke.Entities.Modules
    
Public   Interface  ISearchableInterface ISearchable
        
Function  GetSearchItems() Function  GetSearchItems( ByVal  ModInfo  As  ModuleInfo)  As  SearchItemInfoCollection
    
End Interface
End Namespace

 

 

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

 

 



        
' '' -----------------------------------------------------------------------------
         ' '' <summary>
         ' '' GetSearchItems implements the ISearchable Interface
        ' '' </summary>
         ' '' <remarks>
         ' '' </remarks>
         ' '' <param name="ModInfo">The ModuleInfo for the module to be Indexed</param>
         ' '' <history>
         ' ''        [cnurse]    11/17/2004    documented
         ' '' </history>
         ' '' -----------------------------------------------------------------------------
         Public   Function  GetSearchItems() Function  GetSearchItems( ByVal  ModInfo  As  Entities.Modules.ModuleInfo)  As  Services.Search.SearchItemInfoCollection  Implements  Entities.Modules.ISearchable.GetSearchItems
            
Dim  SearchItemCollection  As   New  SearchItemInfoCollection

            
Dim  Links  As  ArrayList  =  GetLinks(ModInfo.ModuleID)

            
Dim  objLink  As   Object
            
For   Each  objLink  In  Links
                
Dim  SearchItem  As  SearchItemInfo
                
With   CType (objLink, LinkInfo)
                    
'  
                     Dim  UserId  As   Integer   =  Null.NullInteger
                    
If   IsNumeric (.CreatedByUser)  Then
                        UserId 
=   Integer .Parse(.CreatedByUser)
                    
End   If
                    SearchItem 
=   New  SearchItemInfo(ModInfo.ModuleTitle  &   "  -  "   &  .Title, .Description, UserId, .CreatedDate, ModInfo.ModuleID, .ItemId.ToString, .Description,  " ItemId= "   &  .ItemId.ToString, Null.NullInteger)
                    SearchItemCollection.Add(SearchItem)
                
End   With
            
Next

            
Return  SearchItemCollection
        
End Function

 

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

         public  DotNetNuke.Services.Search.SearchItemInfoCollection GetSearchItems(DotNetNuke.Entities.Modules.ModuleInfo ModInfo)
        {
            DotNetNuke.Services.Search.SearchItemInfoCollection searchItems 
=   new  DotNetNuke.Services.Search.SearchItemInfoCollection();
            ArrayList News 
=  List(ModInfo.ModuleID);
            foreach(NewsInfo news 
in  News)
            {
                DotNetNuke.Services.Search.SearchItemInfo item;
                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);
                searchItems.Add(item);
            }
            
return  searchItems;
        }


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

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

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

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

     Public   Enum  DesktopModuleSupportedFeatureEnum DesktopModuleSupportedFeature
        IsPortable 
=   1
        IsSearchable 
=   2
    
End Enum


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

你可能感兴趣的:(搜索引擎)