Hey Chronofied,
When you create a module you can package and install it into a DNN site (I'm sure you know this already). I like to call this "registering" the module with your DotNetNuke site. When you register the module there is a file that describes the module's files so that DNN knows what to do with them (run sql scripts, move user controls to the right folder, move assemblies to the right folder, etc...). This is the .dnn file (commonly referred to as a manifest file). The .dnn.config file is actually the same file - it is renamed with .config after installation. I've always assumed that this is because IIS will never serve a .config file - so it's just kind of "archiving" it as it is not needed after installation.
As for the SQL scripts are just used to create database objects (stored procedures, views, or tables) that your custom module will use.
[Disclaimer, this is not the only way to do it, and I may have left things out, so please ask if you have any questions]
The "DotNetNuke best practice" for database access is as follows:
![](http://weblogs.asp.net/blogs/ianrobinson/WindowsLiveWriter/DotNetNukeArchitectureDiagram_204F/chart_2.jpg)
The user control and business objects are pretty self explanatory (and aren't "unique" to DNN). When a business object needs to retrieve information from the data store, you'll write some code like this: DataReader myReader = DataProvider.Instance().GetMyData(parameter1, parameter2); and will create an instance of the data provider dynamically (using reflection) and then call the appropriate method off of the concrete data provider.
Relevent sections of the web.config:
Connection String
<connectionStrings>
<add name="SiteSqlServer" connectionString="Server=(local);Database=DotNetNuke_2;uid=dnn2_user;pwd=dnn;" providerName="System.Data.SqlClient" />
</connectionStrings>
Data
<data defaultProvider="SqlDataProvider">
<providers>
<clear />
<add name="SqlDataProvider" type="DotNetNuke.Data.SqlDataProvider, DotNetNuke.SqlDataProvider" connectionStringName="SiteSqlServer" upgradeConnectionString="" providerPath="~\Providers\DataProviders\SqlDataProvider\" objectQualifier="dnn_" databaseOwner="dbo" />
</providers>
</data>
Abstract Data Provider
knows how to create an instance of the concrete data provider based on the informaiton in the web.config. Defines the methods that the concrete data provider must implement (but does not implement them itself).
static readonly DataProvider Provider = (DataProvider)Reflection.CreateObject("data", "Engage.Dnn.Module", "");
//"data" above refers to the section of the web.config
SqlDataProvider knows how to actually connect to the database (again, based on the database related web.config entries) and actually implements the methods in the abstract data provider.
Here is the constructor for a SqlDataProvider:
public SqlDataProvider()
{
//Read the configuration specific information for this provider
Provider objProvider = (Provider)_providerConfiguration.Providers[_providerConfiguration.DefaultProvider];
//Read the attributes for this provider
//Get Connection string from web.config
_connectionString = Config.GetConnectionString();
if (_connectionString.Length == 0)
{
//Use connection string specified in provider
_connectionString = objProvider.Attributes["connectionString"];
}
_providerPath = objProvider.Attributes["providerPath"];
_objectQualifier = objProvider.Attributes["objectQualifier"];
if (!String.IsNullOrEmpty(_objectQualifier) && _objectQualifier.EndsWith("_", StringComparison.Ordinal) == false)
{
_objectQualifier += "_";
}
_databaseOwner = objProvider.Attributes["databaseOwner"];
if (!String.IsNullOrEmpty(_databaseOwner) && _databaseOwner.EndsWith(".", StringComparison.OrdinalIgnoreCase) == false)
{
_databaseOwner += ".";
}
}
Application Blocks
is the Microsoft data access library used by the SQL Data Provider and distributed with DotNetNuke.
CBO (Custom Business Objects)
is a DotNetNuke utility for populating a custom business object from a DataReader. The default implementation uses reflection to inspect the object and matches (public) properties with column names in the DataReader. There is an interface that your business object can implement (IHydratable) that allows you to provide an alternative implementation than the default "black box" reflection method. Here is more info on CBO: