New Community Website

Ordinarily, you'd be at the right spot, but we've recently launched a brand new community website... For the community, by the community.

Yay... Take Me to the Community!

The Community Blog is a personal opinion of community members and by no means the official standpoint of DNN Corp or DNN Platform. This is a place to express personal thoughts about DNNPlatform, the community and its ecosystem. Do you have useful information that you would like to share with the DNN Community in a featured article or blog? If so, please contact .

The use of the Community Blog is covered by our Community Blog Guidelines - please read before commenting or posting.

Enterprise Extension Development with DotNetNuke Part Three

This post is a continuation of my ongoing Enterprise Extension Development blog series talking about how to effectively leverage DotNetNuke in complex environments. In Part One we set the stage for why it is important to look at Enterprise Development slightly differently. In part two we started on the slight differences to basic project structures needed to ensure that we can "Compile Anywhere" and move our projects quickly between machines etc. In this part of the series we will take a look at your code structures within, to handle interdependencies etc successfully.

Template Default Structures/Recommendations

If you have started with the basic templates as we outlined in the previous postings you will see a project structure for your module that might look similar to the following. Specifically looking at FOLDERS.

  • ModuleName
    • App_LocalResources
    • Components
    • SqlDataProviderFiles

Your project may be slightly more detailed than the above, however, the general comments on this structure will still apply. You can see from here that you have a fairly detailed project structure. Your App_LocalResources folder for all localization files, your components folder for all of your classes, and then a SqlDataProviders folder that is there for all of your SQL Setup scripts. This project structure works great for one-off modules. But how does this expand to an enterprise situation? How do we build modules that can leverage code that might need to be shared? How can we be assured that eventually we will not create a circular reference between modules as our projects grow in complexity? This is the next question to address.

Possible Solutions

Looking at the structure issue identified above there are many potential solutions. Each of these decisions have their own merits, and depending on the situation the truly correct answer might vary. In this posting I'll detail my preferred solution, I've found that it works for most situations, but your milage may vary.

To help set the stage for a project structures lets consider a situation where we have a solution that we know has a common core set of data that will be used across different modules. For purposes of example lets image a complex public event registration, attendance, and reporting solution. For the most simplistic example lets assume that we will have 5 parts to the total solution: An Admin Module for system configuration, a Reporting module for various system reports, an Event Registration module for users to signup for available events, a My Events module where registered users can review their history of registered events and print tickets, and lastly an Event Manager module which allows privileged users to add/edit/delete events from the system. As you can see here, these modules are truly distinct pieces of functionality, however, there is a lot of shared data and shared objects. We really want to create a structure to allow the modules to be isolated as distinct units, but re-use any common code between all modules, and ideally centralizing things for potential future expansion.

My Recommended Solution

As we look at the above solution there are a number of ways that we could do this. However, in my situation I would see this solution as a 5 module solution, with 5 unique projects inside of a single .SLN file. Each distinct DNN Modules. but each with a distinct layout & set dependency. Additionally, when deployed to DNN, all of these modules should be grouped into their own folder within the DesktopModules folder so that you can easily find all parts. As such, I would recommend the following folder/file structure for this solution with only key files identified. The following tree shows the structure of the "Source" folder within TFS from previous recommendations.

  • Admin
    • App_LocalResources
    • Components
      • Jobs
      • Models
      • Repositories
      • Utility
    • SqlDataProviderFiles
    • Admin.dnn
  • EventManager
    • App_LocalResources
    • EventManager.dnn
  • EventRegistration
    • App_LocalResources
    • EventRegistration.dnn
  • MyEvents
    • App_LocalResources
    • MyEvents.dnn
  • Reports
    • App_LocalResources
    • Reports.dnn
  • EventSystem.sln

As you can see from the above structure we centralize the business logic so that we can have all modules reference a single source. By doing this we will prevent any future expansion from causing a circular reference and make it easy for any new developer to find what they are looking for. For larger teams you can put people on their own modules and once data structures are in place they can work mostly isolated from the rest of the team. If you have a common helper that might be useful to other modules, drop it in the Admin project so all modules could benefit from it.

Conclusion & Coming Up

This gives you a simple project structure to follow, something that you can use to help organize projects and keep things safe to support future expansion. By having distinct modules, you have individual manifests for each, individual installers as well which helps to manage deployment. In the coming posts we will talk about strategies for management of localization in enterprise development and continue discussing how with a project structure like the above how we can make a developers life easier when going from Development to Testing. Feel free to share your comments below.

This article was cross-posted to my Personal Blog.


Bruce de Beer
Great article, well worth the read.
Bruce de Beer Sunday, September 29, 2013 1:53 AM (link)
Real good read, and just what I've been looking for. Thank you.
atariman5000 Wednesday, October 2, 2013 11:53 AM (link)
Mitchel Sellers
Part 4 coming soon!
Mitchel Sellers Wednesday, October 2, 2013 6:54 PM (link)

Comment Form

Only registered users may post comments.


Aderson Oliveira (22)
Alec Whittington (11)
Alessandra Davies (3)
Alex Shirley (10)
Andrew Hoefling (3)
Andrew Nurse (30)
Andy Tryba (1)
Anthony Glenwright (5)
Antonio Chagoury (28)
Ash Prasad (37)
Ben Schmidt (1)
Benjamin Hermann (25)
Benoit Sarton (9)
Beth Firebaugh (12)
Bill Walker (36)
Bob Kruger (5)
Bogdan Litescu (1)
Brian Dukes (2)
Brice Snow (1)
Bruce Chapman (20)
Bryan Andrews (1)
cathal connolly (55)
Charles Nurse (163)
Chris Hammond (213)
Chris Paterra (55)
Clint Patterson (108)
Cuong Dang (21)
Daniel Bartholomew (2)
Daniel Mettler (181)
Daniel Valadas (48)
Dave Buckner (2)
David Poindexter (12)
David Rodriguez (3)
Dennis Shiao (1)
Doug Howell (11)
Erik van Ballegoij (30)
Ernst Peter Tamminga (80)
Francisco Perez Andres (17)
Geoff Barlow (12)
George Alatrash (12)
Gifford Watkins (3)
Gilles Le Pigocher (3)
Ian Robinson (7)
Israel Martinez (17)
Jan Blomquist (2)
Jan Jonas (3)
Jaspreet Bhatia (1)
Jenni Merrifield (6)
Joe Brinkman (274)
John Mitchell (1)
Jon Henning (14)
Jonathan Sheely (4)
Jordan Coopersmith (1)
Joseph Craig (2)
Kan Ma (1)
Keivan Beigi (3)
Kelly Ford (4)
Ken Grierson (10)
Kevin Schreiner (6)
Leigh Pointer (31)
Lorraine Young (60)
Malik Khan (1)
Matt Rutledge (2)
Matthias Schlomann (16)
Mauricio Márquez (5)
Michael Doxsey (7)
Michael Tobisch (3)
Michael Washington (202)
Miguel Gatmaytan (3)
Mike Horton (19)
Mitchel Sellers (40)
Nathan Rover (3)
Navin V Nagiah (14)
Néstor Sánchez (31)
Nik Kalyani (14)
Oliver Hine (1)
Patricio F. Salinas (1)
Patrick Ryan (1)
Peter Donker (54)
Philip Beadle (135)
Philipp Becker (4)
Richard Dumas (22)
Robert J Collins (5)
Roger Selwyn (8)
Ruben Lopez (1)
Ryan Martinez (1)
Sacha Trauwaen (1)
Salar Golestanian (4)
Sanjay Mehrotra (9)
Scott McCulloch (1)
Scott Schlesier (11)
Scott Wilkinson (3)
Scott Willhite (97)
Sebastian Leupold (80)
Shaun Walker (237)
Shawn Mehaffie (17)
Stefan Cullmann (12)
Stefan Kamphuis (12)
Steve Fabian (31)
Steven Fisher (1)
Timo Breumelhof (24)
Tony Henrich (3)
Torsten Weggen (3)
Tycho de Waard (4)
Vicenç Masanas (27)
Vincent Nguyen (3)
Vitaly Kozadayev (6)
Will Morgenweck (40)
Will Strohl (180)
William Severance (5)
What is Liquid Content?
Find Out
What is Liquid Content?
Find Out
What is Liquid Content?
Find Out