Question

J'ai une application Web comprenant les éléments suivants:

  • Un projet Web (avec un fichier web.config contenant une chaîne de connexion, mais pas de code d'accès aux données dans le projet Web)
  • Un projet d'accès aux données qui utilise les classes LINQ-SQL pour fournir des entités à l'interface utilisateur du projet Web (ce projet contient un fichier de paramètres et un fichier app.config, qui comportent tous deux des chaînes de connexion)

Lorsque je construis et déploie, il n'y a pas de fichier de paramètres ni d'app.config dans le répertoire Bin avec le fichier d'accès aux données .dll, mais la modification de la chaîne de connexion dans le fichier web.config ne modifie pas la base de données en conséquence. La chaîne de connexion doit être compilée dans la DLL d'accès aux données.

Ce dont j'ai besoin, c'est d'un fichier de configuration pour l'ensemble de mon déploiement (site Web, dll d'accès aux données, etc.) comportant une chaîne de connexion à utiliser. Pour le moment, plusieurs chaînes de connexion semblent s'habituer ou être codées en dur.

Comment résoudre au mieux ce désordre?

Merci pour toute aide.

Était-ce utile?

La solution

Je n’ai jamais eu de problème avec la couche d'accès aux données (DAL) pouvant utiliser les chaînes de connexion de mon fichier web.config . Habituellement, je copie simplement la section des chaînes de connexion à partir du DAL et je la colle dans le web.config . J'utilise le concepteur DBML pour créer le contexte de données.

Si cela ne fonctionne pas pour vous, vous pouvez spécifier la chaîne de connexion dans le constructeur de contexte de données. Dans votre projet Web, utilisez une classe statique qui charge vos paramètres, y compris vos chaînes de connexion, et lorsque vous créez votre objet DAL (ou le contexte de données, si vous le créez directement), transmettez-le simplement au constructeur.

public static class GlobalSettings
{
    private static string dalConnectionString;
    public static string DALConnectionString
    {
       get
       {
           if (dalConnectionString == null)
           {
              dalConnectionString = WebConfigurationManager
                                      .ConnectionStrings["DALConnectionString"]
                                        .ConnectionString;
           }
           return dalConnectionString;
       }
    }
}
...

using (var context = new DALDataContext(GlobalSettings.DALConnectionString))
{
   ...
}

Autres conseils

Le fichier de configuration du projet de démarrage définira les paramètres de configuration pour tous les projets inclus. Par exemple, si votre projet Web est le projet de démarrage, toute référence à " appSettings " cherchera les paramètres de web.config, cela inclut toutes les références à " appSettings " à partir de votre projet d'accès aux données. Copiez donc tous les paramètres de configuration du fichier app.config du projet d'accès aux données vers le fichier web.config du projet Web.

Lancez votre propre ConnectionFactory basée sur le registre:

  • ajoutez une clé de registre pour votre application sous SOFTWARE / [YOUR_COMPANY] / [YOUR_APP]
  • ajouter une valeur de chaîne pour ConnectionString
  • Apprenez à votre ConnectionFactory à ouvrir la clé de registre appropriée (dans un constructeur statique, toutes les pages ne se chargent pas!).
  • exportez les informations de registre sous forme de fichier .reg, ajoutez-les au contrôle de source, modifiez-les et appliquez-les si nécessaire pour configurer d'autres ordinateurs.

Pro:

  • Simple à configurer
  • Connectionstring vit à un seul endroit
  • Pas dans web / app.config, il n'est donc pas nécessaire de coder en dur les paramètres spécifiques à l'environnement.
  • Pas dans web / app.config, donc Junior Dev Jimmy ne peut pas demander par inadvertance à votre serveur de production de consulter la base de données DEV

Con:

  • Il n'est pas immédiatement évident que des éléments importants résident dans le registre. Par conséquent, les nouveaux développeurs auront besoin d'instructions.
  • Étape supplémentaire lors de la configuration d'un nouvel ordinateur de déploiement
  • Le registre est oldskool. Les développeurs juniors vont se moquer de vous.

Merci pour les réponses.

Ceux d'entre vous qui disent que l'application utilisera les paramètres de web.config sont corrects dans les cas où je les référence dans mon propre code:

_connectionString = ConfigurationManager.AppSettings["ConnectionString"];

.. mais il y a un problème différent avec les datacontexts LINQ-SQL - je pense qu'ils incluent des chaînes de connexions dans la dll compilée à utiliser dans le constructeur sans paramètre. Comme le dit tvanofosson, je dois créer des datacontexts en transmettant une référence à la chaîne de connexion dans le fichier web.config. C’est là que j’entrais dans un enchevêtrement:)

J'ai eu un peu de difficulté avec ce problème aussi. J'ai trouvé une solution en utilisant la définition de classe partielle c # et en étendant le datacontext créé par le concepteur dbml. Cette solution est assez similaire à la réponse de tvanfosson. Ce que vous devez faire est de créer une classe partielle de datacontext avec le constructeur par défaut obtenant ConnectionString à partir de paramètres et, dans les propriétés du concepteur DBML designer, définissez la connexion sur Aucun. De cette façon, la chaîne de connexion ne sera pas compilée dans la DLL. Datacontext obtiendra automatiquement la chaîne de connexion à partir des paramètres de chaîne de connexion web.config. Je n'ai pas testé si cela fonctionnait également avec app.config, mais je pense que cela devrait fonctionner correctement.

Voici un exemple de classe DC partielle:

namespace MyApplication {
    /// <summary>
    /// Summary description for MyDataContext
    /// </summary>
    /// 
    public partial class MyDataContext
    {
        public MyDataContext() :
            base(global::System.Configuration.ConfigurationManager.ConnectionStrings["MyConnectionString"].ConnectionString, mappingSource)
        {
            OnCreated();
        }
    }
}

Votre application utilisera uniquement les entrées de configuration du fichier web.config. Vous pouvez mettre les paramètres de configuration dll dans le fichier web.config tant qu'ils sont correctement structurés. Mon exemple est spécifique à VB en utilisant le My Namespace, mais il vous donne l’idée générale.

Dans le sous-menu configSections du fichier de configuration, vous aurez besoin d’une entrée:

<configSections>
    <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
        <section name="YourAssembly.My.MySettings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
    </sectionGroup></configSections>

Ensuite, dans la partie applicationSettings du fichier de configuration, placez les entrées pour chaque dll:

    <applicationSettings>
      <YourAssembly.My.MySettings>
        <setting name="DebugMode" serializeAs="String">
            <value>False</value>
        </setting>
      </YourAssembly.My.MySettings>
    </applicationSettings>  

Pour le protéger de tout élément du code généré automatiquement, remplacez les informations de connexion dans la méthode OnCreated () du contexte de données:

using System.Configuration;
namespace MyApplication 
{
    partial void OnCreated()
    {
        // attempt to use named connection string from the calling config file
        var conn = ConfigurationManager.ConnectionStrings["MyConnectionString"];
        if (conn != null) Connection.ConnectionString = conn.ConnectionString;
    }
}

De cette manière, le concepteur dbml peut créer des liens (ce qui n’est pas agréable en dehors d’un projet Web), mais vous prenez le contrôle final de la connexion lorsque l’application est exécutée.

Voici une façon de voir les choses. Quel composant doit prendre la décision concernant la base de données à utiliser? Il est possible que la base de données (ou au moins la chaîne de connexion) puisse être modifiée à l'avenir. Le site Web décide-t-il de la base de données à utiliser? Ou bien le DAL décide-t-il?

Si vous disposez de bases de données dev, QA, UAT et prod, la gestion de ces chaînes de connexion est cruciale.

Si le site Web le décide, il doit passer la chaîne de connexion de son Web.config au DAL. Si le site Web n'est pas censé connaître l'origine des données, la chaîne de connexion appartient au DAL.

Que diriez-vous de définir un objet ConnectionFactory, qui prend un enum en paramètre et retourne un objet de connexion complètement formé?

Vous pouvez également demander à l'application Web de fournir la chaîne de connexion lorsqu'elle doit utiliser le projet d'accès aux données. Vous pouvez en faire une partie du constructeur.

Vous pouvez également écrire votre propre logique pour charger une chaîne de connexion à partir d'un fichier externe lorsque le projet d'accès aux données effectue ses appels.

Dans un monde parfait, je pense que vous voudriez refactoriser votre couche de données pour récupérer les paramètres de configuration via System.Configuration ou les constructeurs / usines pertinents. Cela signifie que vous devez recâbler sa source de configuration implicite ou définir explicitement les connexions à partir de son hôte / consommateur. Un autre modèle associé pour centraliser ces types de constantes consiste à insérer une propriété en lecture seule dans une classe d'assistance statique et à laisser cette classe gérer la résolution réelle à partir de configs, etc.

NHibernate et sa gestion de la configuration / mappages constituent un bon exemple de la manière élégante de procéder. Certes, c’est un peu l’enfer xml, et Fluent NHib est plus sucré, mais la plupart des exemples du monde réel vous montreront comment réconcilier la configuration d’un assemblage de support et de l’assemblage en cours d’exécution.

Lancez votre propre ConnectionFactory basée sur les fichiers .config:

  • Définissez une section de configuration personnalisée pour mapper des paires clé / chaîne de connexion
  • Apprenez à votre ConnectionFactory à détecter cette section de configuration en utilisant le nom d'hôte ou le nom de machine, selon le cas
  • Renseignez les valeurs de clé / connectionstring pour vos différents serveurs dev / qa / prod, puis déposez-les dans vos différents fichiers app.config, web.config, etc.

Pro:

  • Toutes les personnes présentes dans le projet, donc pas de surprises
  • L'ajout d'une cible de déploiement supplémentaire est une opération copier / coller dans un fichier .config

Con:

  • Fait pour les grosses sections XML laides, surtout si vous avez une douzaine de serveurs de production
  • Doit être dupliqué entre les projets
  • Besoin de changement de code & amp; redéployer pour ajouter une nouvelle cible
  • Le code doit connaître l'environnement dans lequel il va vivre

Je sais que c'est vieux, mais voici comment je le fais (j'aime assez le chemin de @Seba mais je n'ai pas essayé cela)

Cela suppose que votre fichier DBML réside dans sa propre bibliothèque de classes, ce qui m'a paru le plus pratique lors du partage d'entités et d'accès aux données sur plusieurs sites Web et autres bibliothèques de classes. Cela suppose également que vous avez nommé votre chaîne de connexion de la même manière dans chaque projet. J'utilise NAnt pour définir cela lorsque je déploie dans différents environnements.

Je me suis basé sur la réponse ci-dessus de @tvanfosson - bravo à ce gars-là.

  1. Créez votre propre classe de base, qui dérive de LinqDataContext

Voici le code VB:

    Imports System.Configuration

Public Class CustomDataContextBase
    Inherits System.Data.Linq.DataContext
    Implements IDisposable

    Private Shared overrideConnectionString As String

    Public Shared ReadOnly Property CustomConnectionString As String
        Get
            If String.IsNullOrEmpty(overrideConnectionString) Then
                overrideConnectionString = ConfigurationManager.ConnectionStrings("MyAppConnectionString").ConnectionString
            End If

            Return overrideConnectionString
        End Get
    End Property

    Public Sub New()
        MyBase.New(CustomConnectionString)
    End Sub

    Public Sub New(ByVal connectionString As String)
        MyBase.New(CustomConnectionString)
    End Sub

    Public Sub New(ByVal connectionString As String, ByVal mappingSource As System.Data.Linq.Mapping.MappingSource)
        MyBase.New(CustomConnectionString, mappingSource)
    End Sub

    Public Sub New(ByVal connection As IDbConnection, ByVal mappingSource As System.Data.Linq.Mapping.MappingSource)
        MyBase.New(CustomConnectionString, mappingSource)
    End Sub

End Class
  1. Ouvrez votre fichier DBML et, dans les propriétés, ajoutez le nom de la classe ci-dessus à la propriété Classe de base.

Remarque, si vous avez placé la classe de contexte de données personnalisée dans le même assemblage, incluez simplement le nom de la classe, par exemple. CustomDataContext.

S'ils se trouvent dans des assemblys différents, utilisez le nom complet, par exemple. MyCo.MyApp.Data.CustomDataContext

  1. Pour vous assurer que le logiciel Designer fonctionne correctement, copiez votre chaîne de connexion dans le fichier app.config de la bibliothèque de classes. Cela ne sera pas utilisé en dehors de l'EDI.

C'est ça.

Vous devrez nommer votre chaîne de connexion de la même manière

Ce que vous faites essentiellement consiste à forcer le contexte de données à ignorer les informations de connexion définies dans le fichier DBML. Utiliser les méthodes du ConfigurationManager signifie qu’il récupérera la chaîne de connexion de l’assembly appelant.

HTH

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top