views:

128

answers:

3

Hi,

I have multiple DLLs that are used to read/write data into my database.

There is a presentation layer DLL and a data access layer DLL. I want these DLLs to share a set of the connection strings.

My idea is to store the connection string in a seperate DLL in the external configuration file. I'm not sure whether it's a good idea and whether I can reference that external DLL in both presentation and data access layers.

The other question is whether I should write a helper class to read the data from the external config file or whether I should be using built in .Net methods?

Thank you

+1  A: 

As far as I'm aware, DLL files cannot make use of .net config items like app.config files, so if you want your dll to be configurable through say an xml file, you'll have to write it yourself.

AndyC
Hey, so should I reference an external .config file within web.config or should I just write a separate layer which will read the external .config file directly?
vikp
A: 

I can store the connection string in the machine.config, but once again not sure about all the implications....

vikp
+2  A: 

Isolate the configuration file access code in a separate class. Make the configuration data (connectionstrings and whatnot) available via an interface on that class. Let the interface live in a shared assembly. Let any class that needs this interface get a reference to an instance of the configuration class via dependency injection. If you're not already using a DI framework I can highly recommend Autofac.

What have you achieved? Presentation and data access classes are now only dependent on a shared interface definition. They don't care what the implementation of that interface is, whether it reads connection strings from web.config, machine.config or some other store. Even better, you can now more easily test your classes by faking the implementation.

Update: First, to illustrate making the configuration data available via an interface. Say we have the following conffiguration service:

public interface IConfigurationService
{
    string ConnectionString {get;}
}

public class ConfigurationService : IConfigurationService
{
    string ConnectionString {get;}

    public ConfigurationService()
    {
        // load configuration
    }
}

My data access class could use this class directly:

public class DataAccess
{
    private string _connectionString;

    public DataAccess()
    {
        var config = new ConfigurationService();
        _connectionString = config.ConnectionString;
    }
}

The problem with this approach is coupling. DataAccess is now directly dependent on the ConfigurationService class. Any tests we write for DataAccess will inadvertently be affected by the ConfigurationService class. Also, should we need to switch out the implementation of ConfigurationService it would require changes to DataAccess (and all other classes directly dependent on this class).

To solve this, we invert the dependency hierarchy and references an interface instead of the concrete class, like this:

public class DataAccess
{
    private string _connectionString;

    public DataAccess(IConfigurationService configurationService)
    {
        _connectionString = configurationService.ConnectionString;
    }
}

The data access class is now oblivious as to what the configuration service implementation is and how that instance is created.

Peter Lillevold
Hey! Thank you for the reply. I'm clear with keeping configuration related code in a separate DLL within a class. I'm familiar with interfaces but, I'm not entirely sure what do you mean by making config data available via an interface.Why do you recommend a dependency injection? Can't I just reference my config data layer within each class? e.g. Using ConfigurationUtilities;Everything else makes perfect sense, thank you very much! :)
vikp
@vikp - added some more depth to my answer. Hope it makes it clearer...
Peter Lillevold
Great example, I have been thinking about this before that if one of the concrete classes change I'll have to make alterations in multiple places! Thanks a lot!
vikp