In previous blog posts I have said that Oqtane was "heavily influenced and inspired" by DNN. I realize this statement is rather vague so I thought it may be helpful to provide a bit more detail in order to help clarify the similarities and differences.
From a product perspective, I have always appreciated the value of frameworks. From my very first job out of college where I was tasked with building a fund accounting system on the VAX/VMS platform, I have always tried to focus on productivity and consistency in my software development efforts. Whether this was accomplished through simple automation tools such as code generators or more advanced development frameworks, I have always believed that frameworks are the key to constructing well-structured, maintainable, and testable web applications. Frameworks provide a robust foundation and proven techniques for dealing with your most common development concerns. And from a business perspective it is well understood that pre-built components, reference examples, and availability of developers with shared understanding leads to large-scale time and cost savings. DNN was originally conceived as a web application framework and later shifted its focus to become a content management system. Oqtane's goal is to get back to basics of providing a highly optimized modular application framework for developers.
From an architecture perspective, there were a number of concepts in DNN which were the key differentiators from other .NET development frameworks. These included multi-tenancy, a fully dynamic page compositing model, designer friendly skins, and extensibility via third party modules. And as I said in a previous blog post, I believe that from a development perspective these concepts are just as relevant today as they were 17 years ago when DNN was first released. As original creator of DNN I am intimately familiar with how these features were originally architected so it was logical that I wanted to include them in the MVP feature set for my initial proof of concept of Oqtane in Blazor and .NET Core.
From a philosophical perspective, there is a massive community of developers and users who have relied on DNN for the past 2 decades. As creator of DNN, I have always tried to make decisions which were in the best interest of the community and I continue to feel a sense of personal responsibility to preserve its legacy. So it goes without saying that the uncertainty and lack of clarity when it comes to a future vision for DNN is a major concern for me. One of the significant benefits of using DNN as inspiration for Oqtane is that the community will already be familiar with its core concepts. This familiarity should make people feel immediately comfortable and allow them to become productive very quickly. In fact, there may even be potential for an automated migration path (this should become more obvious below).
Let's look at a few concrete examples of how Oqtane is inspired by DNN...
Focusing on the front-end first, DNN has a dynamic page compositing model which manages how modules are rendered on a page. Rather than using the traditional web development pattern where your application code is implemented directly in a web page file, DNN avoids this tight coupling with an abstraction layer which allows the content of pages in a site to be managed using configuration. The configuration is stored in a database and can be managed via administrative tools which are an integrated part of the page compositing framework. This abstraction layer provides a number of key benefits. It allows a page to be organized into distinct content regions (called Panes) where one or more modules can be dynamically injected at run-time. It also provides granular permissions at the page and module level which can be easily managed through the user interface rather than through hard-coded logic in your application. The page compositing model in DNN was implemented using ASP.NET WebForms technology and relies on User Controls (*.ascx) to provide the componentization capabilities. WebForms is a synchronous server based framework and requires a full page refresh for every user interface interaction. Due to the latency issues with the user experience, the industry has been gradually moving away from this approach for the past decade.
Modules provide the essential extensibility to integrate functionality with the framework. In DNN a module is comprised of one or more user controls which are loaded based on specific Url routing conventions. Basically the Url includes a page specification which provides the scope for the request, and then optionally includes a module identifier and control key in the querystring which the framework utilizes to load the appropriate user control. In order to load a module, DNN requires that the module and its related user controls are first registered in the database alongwith a variety of metadata to define its behavioral characteristics.
Oqtane uses the same conceptual module loading technique but with a few optimizations. In Oqtane a module is comprised of one or more Blazor components and these components are dynamically loaded by the router. Oqtane utilizes a Url convention which is consistent with modern MVC applications where the action method is typically the last segment of the path. In order to reduce the amount of ceremony required to develop modules, Oqtane does not require modules to be registered in the database. Instead it automatically discovers all modules during startup and retrieves the metadata from properties which are declared directly in the code.
Switching to the back-end, DNN has a very mature database model for managing configuration and content. Many developers are very familiar with this data model as it has not changed significantly for many years. A new installation of DNN has more than 140 tables however the "core" schema is comprised of only 14 tables.
Oqtane leverages the same data model as DNN - with a few minor modifications. Table names have been modified to follow consistent naming patterns and to have names which describe their true purpose. Table definitions have been optimized to remove any unused or legacy columns which are no longer applicable. Rather than creating a separate and distinct settings table for each core entity a generic Setting table was introduced which can be used by any entity. Similarly, the permissions tables have been consolidated into a single table which can support any entity which has security requirements. And in order to support additional multi-tenant use cases, the Alias table has been paired with a new Tenant table (see red box in diagram) which can be provisioned independently into the "master" database and provide a dynamic linkage to other "content" databases. Overall, you can see the data model is very consistent with DNN, which is why a number of people have already expressed interest in creating an automated data migration.
It should now be much more clear that Oqtane is influenced and inspired by DNN in multiple ways - both conceptual and concrete. Hopefully the similarities will make Oqtane more attractive to those developers who are familiar with DNN but are looking for a modern alternative. And it should also help those developers who are not familiar with DNN to feel comfortable that Oqtane is built using concepts that have already been validated in enterprise environments for the past 17 years.