Click here to Skip to main content
Click here to Skip to main content
Articles » Web Development » ASP.NET » General » Downloads
 
Add your own
alternative version

Implementing Model-View-Presenter in ASP.NET

, 17 Nov 2007 CPOL
Three implementations of Model-View-Presenter in ASP.NET 2.0.
MVPSampleApp.zip
MVP.SampleApp
Lib
Microsoft.Practices.EnterpriseLibrary.Common.dll
Microsoft.Practices.EnterpriseLibrary.Data.dll
MySql.Data.dll
nunit.framework.dll
Rhino.Mocks.dll
Model
Data
Interfaces
Properties
Presentation
Presentation.Tests
Properties
Interfaces
Properties
SubSonic
ActiveRecord
Builder
CodeGeneration
Templates
CodeLanguage
Configuration
Controls
Calendar
lang
skin
active-bg.gif
calendar.gif
dark-bg.gif
hover-bg.gif
menuarrow.gif
normal-bg.gif
rowhover-bg.gif
status-bg.gif
title-bg.gif
today-bg.gif
Resources
DataProviders
Properties
Sql Tools
SubSonic.snk
Sugar
WebApp
App_Data
Views
SQL2000SampleDb.zip
SQL2000SampleDb.msi
///////////////////////////////////////////////////////
// Code author: Martin Lapierre, http://devinstinct.com
///////////////////////////////////////////////////////

using System;
using System.CodeDom;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using SubSonic.Utilities;

namespace SubSonic
{
    /// <summary>
    /// Provides the features required for code generation. 
    /// </summary>
    public interface ICompileUnitGenerator
    {
        #region Methods

        /// <summary>
        /// Generates the DAL in a single CodeCompileUnit from an input file.
        /// </summary>
        /// <param name="languageType">The language to generate the DAL for.</param>
        /// <param name="inputFile">The path to the input file.</param>
        /// <returns>A single CodeCompileUnit.</returns>
        CodeCompileUnit GenerateSingleUnit(LanguageType languageType, string inputFile);

        /// <summary>
        /// Generates the DAL in multiple CodeCompileUnits from an input file.
        /// </summary>
        /// <param name="languageType">The language to generate the DAL for.</param>
        /// <param name="inputFile">The path to the input file.</param>
        /// <returns>A dictionary of suggested filenames/CodeCompileUnit pairs.</returns>
        IDictionary<string, CodeCompileUnit> GenerateMultipleUnits(LanguageType languageType, string inputFile);

        /// <summary>
        /// Generates the DAL in multiple CodeCompileUnits for specific tables, views
        /// and, optionnaly, all stored procedures.
        /// </summary>
        /// <param name="languageType">The language to generate the DAL for.</param>
        /// <param name="tables">
        /// The list of tables to generate the DAL for; first element as "*" for all tables.
        /// Can be null or empty. A null value generates no table and no table struct. 
        /// <param name="views">
        /// The list of views to generate the DAL for; first element as "*" for all views.
        /// Can be null or empty. A null value generates no view and no view struct. 
        /// </param>
        /// <param name="useSPs">
        /// true to generate the Stored Procedure; false not to generate.
        /// A null value generates Stored Procedures based on the configuration file option.
        /// </param>
        /// <param name="providerName">
        /// The name of the provider to generate the DAL for.
        /// If null, generates code for all the providers.
        /// </param>
        /// <returns>A dictionary of suggested filenames/CodeCompileUnit pairs.</returns>
        IDictionary<string, CodeCompileUnit> GenerateMultipleUnits(LanguageType languageType, string[] tables, string[] views, bool? useSPs, string providerName);

        /// <summary>
        /// Gets the list of tables.
        /// </summary>
        /// <param name="providerName">
        /// The name of the provider to get the tables for.
        /// If null, uses the default provider.
        /// </param>
        /// <returns>A list of table names.</returns>
        string[] GetTableNames(string providerName);

        /// <summary>
        /// Gets the list of views.
        /// </summary>
        /// <param name="providerName">
        /// The name of the provider to get the views for.
        /// If null, uses the default provider.
        /// </param>
        /// <returns>A list of view names.</returns>
        string[] GetViewNames(string providerName);

        /// <summary>
        /// Gets the list of provider names for the current application context.
        /// </summary>
        /// <returns>A list of provider names.</returns>
        string[] GetProviderNames();

        #endregion Methods
    }

    /// <summary>
    /// Hosts the code generation process for any environment.
    /// </summary>
    /// <remarks>
    /// This host allows multiple SubSonic code generators 
    /// to run simultaneously even if the SubSonic core classes are static.
    /// </remarks>
    public class CompileUnitGeneratorHost //: ICompileUnitGenerator
    {
        #region Fields

        /// <summary>
        /// The type of the internal generator.
        /// </summary>
        /// <remarks>
        /// More reliable than using a hard-coded string.
        /// </remarks>
        private static Type _generatorType = typeof(CompileUnitGenerator);

        /// <summary>
        /// The hosted compile unit generator.
        /// </summary>
        private ICompileUnitGenerator _generator = null;

        #endregion Fields


        #region Constructors

        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="path">The path to the project to create the host for.</param>
        public CompileUnitGeneratorHost(string path)
        {
            _generator = CreateGenerator(path);
        }

        #endregion Constructors


        #region Properties

        /// <summary>
        /// Gets the hosted compile unit generator.
        /// </summary>
        public ICompileUnitGenerator Generator
        {
            get { return _generator; }
        }

        #endregion Properties


        #region Methods

        /// <summary>
        /// Creates a CompileUnitGenerator in its own domain.
        /// </summary>
        /// <remarks>
        /// Assigns the configuration file with the highest priority to the newly created AppDomain.
        /// </remarks>
        /// <param name="path">The path to the project to create the generator for.</param>
        /// <returns>The CompileUnitGenerator.</returns>
        [MethodImpl(MethodImplOptions.NoInlining)] // Make sure the method is not inlined by the compiler.
        protected static ICompileUnitGenerator CreateGenerator(string path)
        {
            AppDomainSetup setup = new AppDomainSetup();
            string[] configFiles = ConfigurationProvider.FindProjectConfigFiles(path);

            setup.ApplicationBase = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
            setup.ConfigurationFile = configFiles[0]; // Make System.Configuration.ConfigurationManager use this file in the new AppDomain.
            AppDomain domain = AppDomain.CreateDomain(Guid.NewGuid().ToString(), null, setup);

            return domain.CreateInstanceAndUnwrap(_generatorType.Assembly.FullName, _generatorType.FullName, false, BindingFlags.CreateInstance | BindingFlags.Instance | BindingFlags.Public, null, new object[] { configFiles }, null, null, null) as ICompileUnitGenerator;
        }

        #endregion Methods


        #region Classes

        /// <summary>
        /// Configuration-wise code generator.
        /// </summary>
        /// <remarks>An instance of this class is not thread safe.</remarks>
        private class CompileUnitGenerator : MarshalByRefObject, ICompileUnitGenerator
        {
            #region Constructors

            /// <summary>
            /// Constructor.
            /// </summary>
            /// <param name="configFiles">The configuration files to use as override.</param>
            public CompileUnitGenerator(string[] configFiles)
            {
                // Use the config files as overrides of the hosting process.
                ConfigurationProvider.CurrentInstance.ConfigFileOverrides = configFiles;

                // Hack to support relative path for code templates.
                // Only support current directory relativity (starting with "." or ".\").
                DataService.LoadProviders(); // This is where SubSonic init its configuration... load it now.
                if (!string.IsNullOrEmpty(SubSonicConfig.TemplateDirectory) && (SubSonicConfig.TemplateDirectory == "." || SubSonicConfig.TemplateDirectory.StartsWith(@".\")))
                {
                    string directory = Path.GetDirectoryName(ConfigurationProvider.CurrentInstance.ConfigFileOverrides[0]);
                    if (!directory.EndsWith(Path.DirectorySeparatorChar.ToString()))
                        directory += Path.DirectorySeparatorChar;
                    if (SubSonicConfig.TemplateDirectory == ".")
                        SubSonicConfig.TemplateDirectory = directory;
                    else
                        SubSonicConfig.TemplateDirectory = directory + SubSonicConfig.TemplateDirectory.Substring(2);
                }
            }

            #endregion Constructors


            #region Methods

            /// <summary>
            /// Generates the DAL in a single CodeCompileUnit from an input file.
            /// </summary>
            /// <param name="languageType">The language to generate the DAL for.</param>
            /// <param name="inputFile">The path to the input file.</param>
            /// <returns>A single CodeCompileUnit.</returns>
            public CodeCompileUnit GenerateSingleUnit(LanguageType languageType, string inputFile)
            {
                BuildProvider builder = new BuildProvider();
                string tableText = Utility.GetFileText(inputFile);

                return builder.GenerateSingleUnit(languageType, tableText);
            }

            /// <summary>
            /// Generates the DAL in multiple CodeCompileUnits for specific tables, views
            /// and, optionnaly, all stored procedures.
            /// </summary>
            /// <param name="languageType">The language to generate the DAL for.</param>
            /// <param name="tables">
            /// The list of tables to generate the DAL for; first element as "*" for all tables.
            /// Can be null or empty. A null value generates no table and no table struct. 
            /// <param name="views">
            /// The list of views to generate the DAL for; first element as "*" for all views.
            /// Can be null or empty. A null value generates no view and no view struct. 
            /// </param>
            /// <param name="useSPs">
            /// true to generate the Stored Procedure; false not to generate.
            /// A null value generates Stored Procedures based on the configuration file option.
            /// </param>
            /// <param name="providerName">
            /// The name of the provider to generate the DAL for.
            /// If null, generates code for all the providers.
            /// </param>
            /// <returns>A dictionary of suggested filenames/CodeCompileUnit pairs.</returns>
            public IDictionary<string, CodeCompileUnit> GenerateMultipleUnits(LanguageType languageType, string[] tables, string[] views, bool? useSPs, string providerName)
            {
                BuildProvider builder = new BuildProvider();
                return builder.GenerateMultipleUnits(languageType, tables, views, useSPs, providerName);
            }

            /// <summary>
            /// Generates the DAL in multiple CodeCompileUnits from an input file.
            /// </summary>
            /// <param name="languageType">The language to generate the DAL for.</param>
            /// <param name="inputFile">The path to the input file.</param>
            /// <returns>A dictionary of suggested filenames/CodeCompileUnit pairs.</returns>
            public IDictionary<string, CodeCompileUnit> GenerateMultipleUnits(LanguageType languageType, string inputFile)
            {
                string tableText = Utility.GetFileText(inputFile);
                string[] tables = tableText.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
                string[] views = new string[] { "*" };

                // Use input file for tables; always generate views; generate SP based on config file.
                return GenerateMultipleUnits(languageType, tables, views, null, null);
            }

            /// <summary>
            /// Gets the list of tables.
            /// </summary>
            /// <param name="providerName">
            /// The name of the provider to get the tables for.
            /// If null, uses the default provider.
            /// </param>
            /// <returns>A list of table names.</returns>
            public string[] GetTableNames(string providerName)
            {
                //if (String.IsNullOrEmpty(providerName))
                //    return DataService.GetTableNames(providerName);
                //else
                    return DataService.GetTableNames(providerName);
            }

            /// <summary>
            /// Gets the list of views.
            /// </summary>
            /// <param name="providerName">
            /// The name of the provider to get the views for.
            /// If null, uses the default provider.
            /// </param>
            /// <returns>A list of view names.</returns>
            public string[] GetViewNames(string providerName)
            {
                //if (String.IsNullOrEmpty(providerName))
                //    return DataService.GetViewNames();
                //else
                    return DataService.GetViewNames(providerName);
            }

            /// <summary>
            /// Gets the list of provider names for the current application context.
            /// </summary>
            /// <returns>A list of provider names.</returns>
            public string[] GetProviderNames()
            {
                List<string> providerNames = new List<string>();
                foreach(DataProvider provider in DataService.Providers)
                    providerNames.Add(provider.Name);
                return providerNames.ToArray();
            }

            #endregion Methods
        }

        #endregion Classes
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Alex Mueller
Web Developer
United States United States
No Biography provided

| Advertise | Privacy | Mobile
Web03 | 2.8.141015.1 | Last Updated 17 Nov 2007
Article Copyright 2007 by Alex Mueller
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid