skip to the main content area of this page
Patterns and Practices

Repository Factory Enhancements to Use ConnectionStringSettings


Based on a couple of requests in the CodePlex RepositoryFactory Forums, I have made the following source code available for those interested in passing in a connection string during runtime to the RepositoryFactory Class as opposed to reading the connection string from configuration. I have not included any of the unit tests, mocks, and other testing goo for brevity.

Note that passing connection strings around in your application with security information, such as usernames and passwords, is insecure and not a proven practice :)

As changes are made to the RepositoryFactory by the community, this code may no longer be valid, appropriate, or work as intended. Use at your own risk.

// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY

// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT

// LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND

// FITNESS FOR A PARTICULAR PURPOSE.

 

The expected use is as follows:

ConnectionStringSettings settings =

    new ConnectionStringSettings(

        "MyConnectionString",

        "server=...",

        "System.Data.SqlClient");

 

IMyRepository repository =

    RepositoryFactory.Create<IMyRepository>(settings);

 

 

RepositoryFactory Class - Add the following 2 methods to the RepositoryFactory Class for accepting ConnectionStringSettings as a parameter:

 

/// <summary>

/// Creates an instance of a repository with the given interface.

/// </summary>

/// <typeparam name="TInterface">Interface type of the repository.</typeparam>

/// <param name="connectionStringSettings">Connection string settings used to initiliaze the repository.</param>

/// <returns>An instance of a repository implementing the given interface.</returns>

public static TInterface Create<TInterface>(ConnectionStringSettings connectionStringSettings)

{

    return (TInterface)Create(typeof(TInterface), connectionStringSettings);

}

 

/// <summary>

/// Creates an instance of a repository with the given interface type.

/// </summary>

/// <param name="repositoryInterface">Interface type of the repository.</param>

/// <param name="connectionStringSettings">Connection string settings used to initialize the repository.</param>

/// <returns>An instance of a repository implementing the given interface type.</returns>

public static object Create(Type repositoryInterface, ConnectionStringSettings connectionStringSettings)

{

    if (repositoryInterface == null)

        throw new ArgumentNullException("repositoryInterface");

 

    if (connectionStringSettings == null)

        throw new ArgumentNullException("connectionStringSettings");

 

    Type repositoryType = GetRepositoryType(repositoryInterface);

 

    return Activator.CreateInstance(repositoryType, connectionStringSettings);

}

 

 

Repository Class - Add a new constructor to the Repository Class for accepting ConnectionStringSettings as a parameter:

 

/// <summary>

/// Creates an instance of Repository class.

/// </summary>

/// <param name="connectionStringSettings">Connection string settings.</param>

public Repository(ConnectionStringSettings connectionStringSettings)

{

    this.databaseName = connectionStringSettings.Name;

    this.db = new CustomDatabaseFactory().Create(connectionStringSettings);

}

 

 

CustomDatabaseFactory - Add a new class to the Microsoft.Practices.Repository Assembly that creates a database from a ConnectionStringsSettings using various classes that are a part of the Enterprise Library Data Access Application Block:

 

using System;

using System.Configuration;

using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;

using Microsoft.Practices.EnterpriseLibrary.Data;

using Microsoft.Practices.EnterpriseLibrary.Data.Configuration;

 

namespace Microsoft.Practices.Repository

{

    /// <summary>

    /// A workaround to creating a  Database Class similar to the

    /// DatabaseFactory Class in DAAB in situations where you

    /// have a connection string.

    /// </summary>

    public class CustomDatabaseFactory

    {

        private readonly IConfigurationSource _source;

 

        /// <summary>

        /// Creates an instance of the CustomDatabaseFactory

        /// </summary>

        public CustomDatabaseFactory() : this(ConfigurationSourceFactory.Create()) { }

 

        /// <summary>

        /// Creates an instance of the CustomDatabaseFactory

        /// </summary>

        /// <param name="source">The configurationsource.</param>

        public CustomDatabaseFactory(IConfigurationSource source)

        {

            if (source == null)

                throw new ArgumentNullException("source");

 

            _source = source;

        }

 

        /// <summary>

        /// Creates a database using the connection string settings.

        /// </summary>

        /// <param name="connectionStringSettings">The ConnectionStringSettings.</param>

        /// <returns>An instance of the database class.</returns>

        public Database Create(ConnectionStringSettings connectionStringSettings)

        {

            ValidateConnectionStringSettings(connectionStringSettings);

 

            DatabaseConfigurationView view = new DatabaseConfigurationView(_source);

 

            if (view == null)

                throw new ConfigurationErrorsException("Cannot create DatabaseConfigurationView. Check configuration.");

 

            DbProviderMapping mapping = view.GetProviderMapping(connectionStringSettings.Name, connectionStringSettings.ProviderName);

 

            if (mapping == null)

                throw new ConfigurationErrorsException(string.Format("Cannot find a database provider for providername {0}", connectionStringSettings.ProviderName));

 

            return (Database)Activator.CreateInstance(mapping.DatabaseType, connectionStringSettings.ConnectionString);

        }

 

        private void ValidateConnectionStringSettings(ConnectionStringSettings connectionStringSettings)

        {

            if (connectionStringSettings == null)

                throw new ArgumentNullException("connectionStringSettings");

 

            if (string.IsNullOrEmpty(connectionStringSettings.Name))

                throw new ArgumentNullException("connectionStringSettings.Name");

 

            if (string.IsNullOrEmpty(connectionStringSettings.ConnectionString))

                throw new ArgumentNullException("connectionStringSettings.ConnectionString");

 

            if (string.IsNullOrEmpty(connectionStringSettings.ProviderName))

                throw new ArgumentNullException("connectionStringSettings.ProviderName");

        }

    }

}

 

 

EntityRepository.t4 Template - Add a constructor to the EntityRepository.t4 Template that accepts ConnectionStringSettings as a parameter:

 

public <#= entity.Name #>Repository(ConnectionStringSettings connectionStringSettings) : base(connectionStringSettings)
{
}

 

End of Code


Tags: DataAccessApplicationBlock, DataAccessLayer


Topics



Popular Tags



Recent Links