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
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Data.SqlClient;
using System.Data;
using System.Data.Common;
using SubSonic.Utilities;

namespace SubSonic
{

    /// Big thanks to Brenton Webster the code contained herein...
    /// <summary>
    /// Indicates that a per-thread shared DbConnection object should be used the default DataProvider
    /// (or alternativley a specific DataProvider if one is given) when communicating with the database.
    /// 
    /// This class is designed to be used within a using () {} block and in conjunction with a TransactionScope object.
    /// It's purpose is to force a common DbConnection object to be used which has the effect of avoiding promotion 
    /// of a System.Transaction ambient Transaction to the DTC where possible.
    /// 
    /// When this class is created, it indicates to the underlying DataProvider that is should use a shared DbConnection
    /// for subsequent operations. When the class is disposed (ie the using() {} block ends) it will indicate to the 
    /// underlying provider that it should no longer it's current shared connection and should Dispose() it.
    /// </summary>
    public class SharedDbConnectionScope
         : IDisposable
    {
        private bool _disposed;
        private DataProvider _dataProvider;

        /// <summary>
        /// Used to support nesting. By keeping a stack of all instances of the class that are created on this thread
        /// thread we know when it is safe to Reset the underlying shared connection.
        /// </summary>
        [ThreadStatic]
        private static Stack<SharedDbConnectionScope> __instances;

        /// <summary>
        /// Provides access to underlying connection that is shared per thread
        /// </summary>
        public DbConnection CurrentConnection
        {
            get { return _dataProvider.CurrentSharedConnection; }
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        public void Dispose(bool disposing)
        {
            if (!_disposed)
            {
                if (disposing)
                {
                    // remove this instance from the stack
                    __instances.Pop();

                    // if we are the last instance, reset the connection
                    if (__instances.Count == 0)
                        _dataProvider.ResetSharedConnection();

                    _disposed = true;
                }
            }
        }

        /// <summary>
        /// Indicates to the default DataProvider that it should use a per-thread shared connection.
        /// </summary>
        public SharedDbConnectionScope()
            : this(DataService.Provider)
        {
        }

        /// <summary>
        /// Indicates to the default DataProvider that it should use a per-thread shared connection using the given connection string.
        /// </summary>
        /// <param name="connectionString"></param>
        public SharedDbConnectionScope(string connectionString)
            : this(DataService.Provider, connectionString)
        {
        }

        /// <summary>
        /// Indicates to the specified DataProvider that it should use a per-thread shared connection.
        /// </summary>
        /// <param name="dataProvider"></param>
        public SharedDbConnectionScope(DataProvider dataProvider)
        {
            if (dataProvider == null)
                throw new ArgumentNullException("dataProvider");

            _dataProvider = dataProvider;
            _dataProvider.InitializeSharedConnection();

            if (__instances == null)
                __instances = new Stack<SharedDbConnectionScope>();
            __instances.Push(this);
        }

        /// <summary>
        /// Indicates to the specified DataProvider that it should use a per-thread shared connection using the given connection string.
        /// </summary>
        /// <param name="dataProvider"></param>
        /// <param name="connectionString"></param>
        public SharedDbConnectionScope(DataProvider dataProvider, string connectionString)
        {
            if (dataProvider == null)
                throw new ArgumentNullException("dataProvider");
            if (connectionString == null)
                throw new ArgumentNullException("connectionString");
            if (String.IsNullOrEmpty(connectionString))
                throw new ArgumentException("connectionString can not be empty");

            _dataProvider = dataProvider;
            _dataProvider.InitializeSharedConnection(connectionString);

            if (__instances == null)
                __instances = new Stack<SharedDbConnectionScope>();
            __instances.Push(this);
        }
    }

    /// <summary>
    /// Used within SubSonic to automatically manage a SqlConnection. If a shared connection is available 
    /// for the specified provider on the current thread, that shared connection will be used. 
    /// Otherwise, a new connection will be created.
    /// Note that if a shared connection is used, it will NOT be automatically disposed - that is up to the caller.
    /// Lifetime management of the shared connection is taken care of by using a <see cref="SharedDbConnectionScope"/> 
    /// If a new connection is created, it will be automatically dsiposed when this AutomaticConnectionScope object
    /// is disposed.
    /// </summary>
    internal class AutomaticConnectionScope
        : IDisposable
    {
        private DbConnection _dbConnection;
        private bool _isUsingSharedConnection;
        private bool _disposed;

        internal DbConnection Connection
        {
            get { return _dbConnection; }
        }

        internal bool IsUsingSharedConnection
        {
            get { return _isUsingSharedConnection; }
        }

        internal AutomaticConnectionScope(DataProvider provider)
        {
            if (provider == null)
                throw new ArgumentNullException("provider");

            if (provider.CurrentSharedConnection != null)
            {
                _dbConnection = provider.CurrentSharedConnection;
                _isUsingSharedConnection = true;
            }
            else
                _dbConnection = provider.CreateConnection();
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        public void Dispose(bool disposing)
        {
            if (!_disposed)
            {
                if (disposing)
                {
                    // only dispose the connection if it is not a shared one
                    if (!_isUsingSharedConnection)
                        _dbConnection.Dispose();
                    _disposed = true;
                }
            }
        }

        public T GetConnection<T>()
            where T : DbConnection
        {
            return (T)Connection;
        }
    }

}

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 | Terms of Use | Mobile
Web04 | 2.8.150129.1 | Last Updated 17 Nov 2007
Article Copyright 2007 by Alex Mueller
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid