mojoPortal中建立索引时使用了Provider模式,学习一下。
第一步 Main provider class
具体实现为是:
IndexBuilderProvider
代码如下:
public abstract class IndexBuilderProvider : ProviderBase

{
public abstract void RebuildIndex(
PageSettings pageSettings,
string indexPath);


public abstract void ContentChangedHandler(
object sender,
ContentChangedEventArgs e);
}
定义了2个抽象方法
第二步: Provider Collection 类
具体实现为IndexBuilderProviderCollection
代码如下:
public class IndexBuilderProviderCollection : ProviderCollection

{
public override void Add(ProviderBase provider)

{
if (provider == null)
throw new ArgumentNullException("The provider parameter cannot be null.");

if (!(provider is IndexBuilderProvider))
throw new ArgumentException("The provider parameter must be of type IndexBuilderProvider.");

base.Add(provider);
}

new public IndexBuilderProvider this[string name]

{

get
{ return (IndexBuilderProvider)base[name]; }
}

public void CopyTo(IndexBuilderProvider[] array, int index)

{
base.CopyTo(array, index);
}
}
第三步:Provider Configuration 类
具体为IndexBuilderConfiguration类
代码如下:

Code
public class IndexBuilderConfiguration

{
private static readonly ILog log
= LogManager.GetLogger(typeof(IndexBuilderConfiguration));


private ProviderSettingsCollection providerSettingsCollection
= new ProviderSettingsCollection();

public ProviderSettingsCollection Providers

{

get
{ return providerSettingsCollection; }
}

public static IndexBuilderConfiguration GetConfig()

{
try

{
if (
(HttpRuntime.Cache["mojoIndexBuilderConfiguration"] != null)
&& (HttpRuntime.Cache["mojoIndexBuilderConfiguration"] is IndexBuilderConfiguration)
)

{
return (IndexBuilderConfiguration)HttpRuntime.Cache["mojoIndexBuilderConfiguration"];
}

IndexBuilderConfiguration indexBuilderConfig
= new IndexBuilderConfiguration();

String configFolderName = "~/Setup/indexbuilderconfig/";

string pathToConfigFolder
= HttpContext.Current.Server.MapPath(configFolderName);


if (!Directory.Exists(pathToConfigFolder)) return indexBuilderConfig;

DirectoryInfo directoryInfo
= new DirectoryInfo(pathToConfigFolder);

FileInfo[] configFiles = directoryInfo.GetFiles("*.config");

foreach (FileInfo fileInfo in configFiles)

{
XmlDocument configXml = new XmlDocument();
configXml.Load(fileInfo.FullName);
indexBuilderConfig.LoadValuesFromConfigurationXml(configXml.DocumentElement);

}

AggregateCacheDependency aggregateCacheDependency
= new AggregateCacheDependency();

string pathToWebConfig
= HttpContext.Current.Server.MapPath("~/Web.config");

aggregateCacheDependency.Add(new CacheDependency(pathToWebConfig));

System.Web.HttpRuntime.Cache.Insert(
"mojoIndexBuilderConfiguration",
indexBuilderConfig,
aggregateCacheDependency,
DateTime.Now.AddYears(1),
TimeSpan.Zero,
System.Web.Caching.CacheItemPriority.Default,
null);

return (IndexBuilderConfiguration)HttpRuntime.Cache["mojoIndexBuilderConfiguration"];

}
catch (HttpException ex)

{
log.Error(ex);

}
catch (System.Xml.XmlException ex)

{
log.Error(ex);

}
catch (ArgumentException ex)

{
log.Error(ex);

}
catch (NullReferenceException ex)

{
log.Error(ex);

}

return null;

}

public void LoadValuesFromConfigurationXml(XmlNode node)

{
foreach (XmlNode child in node.ChildNodes)

{
if (child.Name == "providers")

{
foreach (XmlNode providerNode in child.ChildNodes)

{
if (
(providerNode.NodeType == XmlNodeType.Element)
&& (providerNode.Name == "add")
)

{
if (
(providerNode.Attributes["name"] != null)
&& (providerNode.Attributes["type"] != null)
)

{
ProviderSettings providerSettings
= new ProviderSettings(
providerNode.Attributes["name"].Value,
providerNode.Attributes["type"].Value);

providerSettingsCollection.Add(providerSettings);
}

}
}

}
}
}


}
第四步: Provider Manager 类
具体实现 IndexBuilderManager
代码如下:

代码
public sealed class IndexBuilderManager

{
//private static bool isInitialized = false;
//private static Exception initializationException;
private static object initializationLock = new object();
private static readonly ILog log
= LogManager.GetLogger(typeof(IndexBuilderManager));

static IndexBuilderManager()

{
Initialize();
}

private static void Initialize()

{
providerCollection = new IndexBuilderProviderCollection();

try

{
IndexBuilderConfiguration config
= IndexBuilderConfiguration.GetConfig();

if (config != null)

{

if (
(config.Providers == null)
|| (config.Providers.Count < 1)
)

{
throw new ProviderException("No IndexBuilderProvider found.");
}

ProvidersHelper.InstantiateProviders(
config.Providers,
providerCollection,
typeof(IndexBuilderProvider));

}
else

{
// config was null, not a good thing
log.Error("IndexBuilderConfiguration could not be loaded so empty provider collection was returned");

}
}
catch (NullReferenceException ex)

{
log.Error(ex);
}
catch (TypeInitializationException ex)

{
log.Error(ex);
}
catch (ProviderException ex)

{
log.Error(ex);
}
providerCollection.SetReadOnly();
//}
//catch (Exception ex)
//{
// log.Error(ex);
// initializationException = ex;
// isInitialized = false;
// //throw ex;
// return;
//}

//isInitialized = true;
}


private static IndexBuilderProviderCollection providerCollection;

public static IndexBuilderProviderCollection Providers

{
get

{
//try
//{
if (providerCollection == null) Initialize();
return providerCollection;
//}
//catch (NullReferenceException ex)
//{
// log.Error(ex);
//}
//catch (TypeInitializationException ex)
//{
// log.Error(ex);
//}
//catch (ProviderException ex)
//{
// log.Error(ex);
//}

return null;
}
}
}
第五步:继承抽象Provider类的子类
具体实现: BlogIndexBuilderProvider

代码
public class BlogIndexBuilderProvider : IndexBuilderProvider

{
public BlogIndexBuilderProvider()

{ }

private static readonly ILog log
= LogManager.GetLogger(typeof(BlogIndexBuilderProvider));

public override void RebuildIndex(
PageSettings pageSettings,
string indexPath)

{
if (pageSettings == null)

{
if (log.IsErrorEnabled)

{
log.Error("pageSettings object passed to BlogIndexBuilderProvider.RebuildIndex was null");
}
return;
}
log.Info("BlogIndexBuilderProvider indexing page - "
+ pageSettings.PageName);

//try
//{
Guid blogFeatureGuid = new Guid("026cbead-2b80-4491-906d-b83e37179ccf");
ModuleDefinition blogFeature = new ModuleDefinition(blogFeatureGuid);

List<PageModule> pageModules
= PageModule.GetPageModulesByPage(pageSettings.PageId);

DataTable dataTable
= Blog.GetBlogsByPage(
pageSettings.SiteId,
pageSettings.PageId);

foreach (DataRow row in dataTable.Rows)

{
IndexItem indexItem = new IndexItem();
indexItem.SiteId = pageSettings.SiteId;
indexItem.PageId = pageSettings.PageId;
indexItem.PageName = pageSettings.PageName;
indexItem.ViewRoles = pageSettings.AuthorizedRoles;
indexItem.FeatureName = blogFeature.FeatureName;
indexItem.FeatureResourceFile = blogFeature.ResourceFile;

indexItem.ItemId = Convert.ToInt32(row["ItemID"], CultureInfo.InvariantCulture);
indexItem.ModuleId = Convert.ToInt32(row["ModuleID"], CultureInfo.InvariantCulture);
indexItem.ModuleTitle = row["ModuleTitle"].ToString();
indexItem.Title = row["Title"].ToString();
indexItem.ViewPage = "BlogView.aspx";
indexItem.Content = row["Description"].ToString();
int commentCount = Convert.ToInt32(row["CommentCount"]);

if (commentCount > 0)

{ // index comments
StringBuilder stringBuilder = new StringBuilder();
DataTable comments = Blog.GetBlogCommentsTable(indexItem.ModuleId, indexItem.ItemId);

foreach (DataRow commentRow in comments.Rows)

{
stringBuilder.Append(" " + commentRow["Comment"].ToString());
stringBuilder.Append(" " + commentRow["Name"].ToString());

if (log.IsDebugEnabled) log.Debug("BlogIndexBuilderProvider.RebuildIndex add comment ");

}

indexItem.OtherContent = stringBuilder.ToString();

}

// lookup publish dates
foreach (PageModule pageModule in pageModules)

{
if (indexItem.ModuleId == pageModule.ModuleId)

{
indexItem.PublishBeginDate = pageModule.PublishBeginDate;
indexItem.PublishEndDate = pageModule.PublishEndDate;
}
}

IndexHelper.RebuildIndex(indexItem, indexPath);

if (log.IsDebugEnabled) log.Debug("Indexed " + indexItem.Title);

}
//}
//catch (Exception ex)
//{
// log.Error(ex);
//}

}


public override void ContentChangedHandler(
object sender,
ContentChangedEventArgs e)

{
Blog blog = (Blog)sender;
if (e.IsDeleted)

{
// get list of pages where this module is published
List<PageModule> pageModules
= PageModule.GetPageModulesByModule(blog.ModuleId);

foreach (PageModule pageModule in pageModules)

{
IndexHelper.RemoveIndexItem(
pageModule.PageId,
blog.ModuleId,
blog.ItemId);
}
}
else

{
IndexItem(blog);
}


}

private static void IndexItem(Blog blog)

{
SiteSettings siteSettings = CacheHelper.GetCurrentSiteSettings();
if (siteSettings == null)

{
if (log.IsErrorEnabled)

{
log.Error("siteSettings retrieved in BlogIndexBuilderProvider.IndexItem was null");
}
return;
}

if (blog == null)

{
if (log.IsErrorEnabled)

{
log.Error("blog object passed to BlogIndexBuilderProvider.IndexItem was null");
}
return;
}

Module module = new Module(blog.ModuleId);
Guid blogFeatureGuid = new Guid("026cbead-2b80-4491-906d-b83e37179ccf");
ModuleDefinition blogFeature = new ModuleDefinition(blogFeatureGuid);

// get comments so they can be indexed too
StringBuilder stringBuilder = new StringBuilder();
IDataReader comments = Blog.GetBlogComments(blog.ModuleId, blog.ItemId);
while (comments.Read())

{
stringBuilder.Append(" " + comments["Comment"].ToString());
stringBuilder.Append(" " + comments["Name"].ToString());

if (log.IsDebugEnabled) log.Debug("BlogIndexBuilderProvider.IndexItem add comment ");

}
comments.Close();

// get list of pages where this module is published
List<PageModule> pageModules
= PageModule.GetPageModulesByModule(blog.ModuleId);

foreach (PageModule pageModule in pageModules)

{
PageSettings pageSettings
= new PageSettings(
siteSettings.SiteId,
pageModule.PageId);

IndexItem indexItem = new IndexItem();
indexItem.SiteId = siteSettings.SiteId;
indexItem.PageId = pageSettings.PageId;
indexItem.PageName = pageSettings.PageName;
indexItem.ViewRoles = pageSettings.AuthorizedRoles;
indexItem.ViewPage = "BlogView.aspx";
indexItem.ItemId = blog.ItemId;
indexItem.ModuleId = blog.ModuleId;
indexItem.ModuleTitle = module.ModuleTitle;
indexItem.Title = blog.Title;
indexItem.Content = blog.Description;
indexItem.FeatureName = blogFeature.FeatureName;
indexItem.FeatureResourceFile = blogFeature.ResourceFile;

indexItem.OtherContent = stringBuilder.ToString();
indexItem.PublishBeginDate = pageModule.PublishBeginDate;
indexItem.PublishEndDate = pageModule.PublishEndDate;

IndexHelper.RebuildIndex(indexItem);
}

if (log.IsDebugEnabled) log.Debug("Indexed " + blog.Title);
}

}