The Code Reference of the Sitefinity Module Builder makes it simple to get started building custom widgets and components to interact with your Dynamic Modules. However, the generated code is specific to each module and type, requiring that you pass in the full type as a string, resolving the type at runtime.
But what if you need to write generic code that could be used for multiple dynamic modules, where you won’t necessarily know in advance what the types are?
The answer is the ModuleBuilderManager, which exposes methods for retrieving both modules and their associated types. Let’s take a closer look at what you need to do to query modules and types..
For this example I’ve created a few sample dynamic modules, leaving one in a disabled state so you can see how the results differ.
We’ll begin by first querying the ModuleBuilderManager for the list of DynamicModules and output the results:
ModuleBuilderManager dynMgr = ModuleBuilderManager.GetManager();
var modules = dynMgr.GetItems(typeof(DynamicModule), "", "", 0, 0).Cast<DynamicModule>();
Response.Write("<h1>Dynamic Modules</h1>");
foreach (var module in modules)
{
Response.Write(string.Format("<p>Module Name: {0}<br />Module Status: {1}<br />Module Types: {2}</p>", module.Name, module.Status, module.Types));
}
The GetItems method uses the first Type parameter to get the modules, which we then cast to a strongly-typed list, allowing us to iterate through each module, including the module status.
However, if we look at the output of this list, we see that the Types property is blank. The Types property is supposed to contain a list of the DynamicModuleTypes associated with the module, but debugging the code reveals that this property is null.
I’m not sure why this is null, but it appears to be a limitation of the manager, and is simply not implemented.
Instead, we need to issue a separate call to GetItems, this time passing in the DynamicModuleType to get the types.
Response.Write("<h2>Dynamic Types</h2>");
var dynamicTypes = dynMgr.GetItems(typeof(DynamicModuleType), "", "", 0, 0);
foreach (DynamicModuleType dynamicType in dynamicTypes)
{
Response.Write(string.Format("<p>Type name: {0}<br />ParentModule: {1}<br />ParentModuleId: {2}</p>", dynamicType.TypeName, dynamicType.ParentModuleType, dynamicType.ParentModuleId));
}
Once again, the link between the dynamic type and its parent module is missing, as the ParentModule property is also null.
Fortunately, there is an additional property ParentModuleId which we can use to query the parent module, and ensure that the type we’re using corresponds to a specific module.
By combining these dynamic module queries, we can now work with all Dynamic Modules and Types in a generic, but unified way.
The example below shows how we can use the ModuleBuilderManager in combination with the standard DynamicModuleManager to query all of the published items from all of the modules in a single list, excluding items that are from an inactive module.
// initialize managers
ModuleBuilderManager dynMgr = ModuleBuilderManager.GetManager();
DynamicModuleManager mgr = DynamicModuleManager.GetManager();
// get list of all dynamic modules
var modules = dynMgr.GetItems(typeof(DynamicModule), "", "", 0, 0).Cast<DynamicModule>();
// get list of all dynamic item types
var dynamicTypes = dynMgr.GetItems(typeof(DynamicModuleType), "", "", 0, 0);
foreach (DynamicModuleType dynamicType in dynamicTypes)
{
// ensure parent module is active
var parentModule = modules.FirstOrDefault(m => m.Id == dynamicType.ParentModuleId);
if (parentModule == null || parentModule.Status == DynamicModuleStatus.NotInstalled || parentModule.Status == DynamicModuleStatus.Inactive) continue;
// get the list of published items
var typeName = TypeResolutionService.ResolveType(dynamicType.GetFullTypeName());
var myCollection = mgr.GetDataItems(typeName).Where(i => i.Status == ContentLifecycleStatus.Live);
foreach (var item in myCollection)
Response.Write(string.Format("Title: {0}<br />", item.GetValue("Title")));
}
Now we can see all of the content items from all of the active modules in a single list.
This is actually what we used to update the Falafel Dashboard Widgets for Sitefinity, allowing the content widgets to display counts, details, and comments from all of the Sitefinity modules, including any dynamic ones you create with the Module Builder.
I hope this information was helpful!
Enjoyed this post and/or found it useful?