Accessing keys in appSettings in App.config across multiple projects in solution - c#

I've got a C# solution of about 7 different projects, each with their own class to access our database. Right now I'm storing the database server, username, and password in the AppSettings of the app.config file for the startup project.
App.config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings>
<add key ="dbServer" value="localhost"/>
<add key ="dbUser" value ="admin"/>
<add key ="dbPassword" value ="pw"/>
</appSettings>
...
</configuration>
In the same startup project, I have created a class to query for these values:
public static class DBConfiguration
{
public static String getDBServer
{
get { return ConfigurationManager.AppSettings["dbServer"]; }
}
public static String getDBUser
{
get { return ConfigurationManager.AppSettings["dbUser"]; }
}
public static String getDBPassword
{
get { return ConfigurationManager.AppSettings["dbPassword"]; }
}
}
Right now when I am in my Unit Test project, I am trying to call DBConfiguration.getDBServer, DBConfiguration.getDBUser, etc. and it is returning null. If I copy the same appSettings into the UT app.config, I get results. I'm a little confused how that is working. Since DBConfiguration is located in startup - shouldn't the calls to DBConfiguration refer to the app.config in startup as well?
Also, I have already added the reference to System.Configuration.

What you are seeing is by design. ConfigurationManager will pull settings from the current executing assembly. So if your unit test is the current executing assembly ConfigurationManager will get its settings from that app.config. This is useful for scenarios where you connect to different databases for testing purposes (which...you should be)
EDIT
ok so based on what you just mentioned about how you have things set up I feel compelled to ask why do you have it setup this way, and why do you have checks to see if you are in production or not. Sure there are valid reasons for it, but I think 99% of the time it can be avoided with a little forsight. However since your post was more about the app.config file I'll stick to that. When you have the same devs all needing to test some interaction with the database there are a few approaches one could take. One approach (and the one i'm most familiar with) is to use the repository pattern where you have a interface that returns or sets things according to a class. typical boiler plat code would be something similar to this:
public interface IRobotRepository()
{
IEnumerable<Robot> GetAllRobots();
Robot GetRobot(RobotParameters parameters);
void DeleteRobots();
void DeleteRobot(Robot robotToDelete);
}
granted a repository does not have to have both getters and setters, the point is that it is a way of stating your intent of what you want out of a repository (such as a database). It is simple and the point which is what I'm getting at though. With it you can easily mock it out and test functionality that depends specifically on that data. No specific configuration needed just all in memory things. Then for integration tests you can test that the repositories work as intended. Although you can have said repository on each dev's computer (such as using SqlLocalDb, or Sqlite's in memory database) those require a little more work with keeping it in sync with production. Just gotta balance the cost with that. Another option is to have a common QA/Dev/Sandbox database that is shared. There are tradeoff's with this approach too but normally isn't a big deal.
Keep in mind though that this is just one approach and there are tons of other approaches that people will scream to death is the best way. I just want to point out that there are multiple approaches to having multiple devs testing against a database. I'd be interested to see what your approach ends up being and showing why you went that path.

Related

Settings specific to a class

I have a class where I retrieve certain settings from a database (usernames and passwords). This database is sitting on a network, and it means that if the passwords are changed, I can simply change it in the database, and all the applications that use this class will still work.
I am fully aware of the pros and cons of storing usernames and passwords in a database and in a separate location. I don't want to discuss those, please.
The class has a hard-coded static string that is the path to the database. It is a fully qualified network name (not just the drive letter). I did this because we had an issue where our network DNS got screwed up, and drive letter mappings stopped working, and some people have different drive mappings anyway.
We recently had our server moved, so I now need to go through and change these hard-coded strings.
I was thinking that I should store the path in a settings / configuration file instead. I considered "application.settings", but it is not an application setting; its specific to the class. Is there a preferred way of doing this in the existing .Net framework (this is a C# issue)?
I could simply have a small text or XML file that sits in the application directory, which is probably fine... is there an existing framework namespace or open-source code snippet that someone knows of that I can use?
I think, if you want class specific configuration, you should try to have those class instances, configuration driven. Another way of thinking but; Defining a something in a configuration file, will create an instance of the defined classname.
For example: Create a section, and call it, <Modules> and create items in like: <module type="<namespace>.DBConvertor" param="username=root;passwd=whatever"> This type will be created at startup (you need some coding here). And it's even possible to create more than one instance simultaneously with it's specific configurations.
This kind of configuration is already implemented:
You might take a look at this: "How to: Create Custom Configuration Sections Using ConfigurationSection" https://msdn.microsoft.com/en-us/library/2tw134k3.aspx
And creating instances from typenames, use the Activator class.
Besides that, there are many module/plugin libraries, (like Managed Extensibility Framework (MEF) https://msdn.microsoft.com/en-us/library/dd460648(v=vs.110).aspx but could be a little over the top in this case).

Configuration vs. static properties, security concerns

I'm developing a class library and I need to provide a way to set configuration parameters. I can create a configuration section or I can expose static properties. My concern about static properties is security. What prevents a malicious component from making changes at runtime? For instance, in ASP.NET MVC you configure routes using a static property. Is this secure? Can a malicious component add/remove routes?
How would the "untrusted component" get in my application in the first place? NuGet for example. We don't know what's out there, who did it, and if it contains small bits of undesired state changes.
How would the "untrusted component" run? In ASP.NET all you need is PreApplicationStartMethodAttribute to run some code when the application is starting.
When you consider something as a security threat, you should also think about from whom you are trying to protect.
In order for "malicious code" to alter the values of your static properties, this code would need to be loaded into your AppDomain and run. Now think that a malicious attacker has managed to get his code to run in your AppDomain - are your static properties really your major concern? Such an attacker can probably do a lot worst.
Unless you have a scenario where you need to load an assembly/code originating from external untrusted sources, I think you don't really need to defend against your user accessing your properties (Not from security perspective anyway - usability is another thing).
EDIT - about external untrusted code
I still think this is not really your concern. If I understand correctly, you are developing and providing a library, to be used by some 3rd party in their application.
If the application owner decided to take some external library which he does not trust, add it to his application, and allow it to run, then this is not your concern, it is the application owner's concern.
In this scenario, everything I said above still applies. The malicious code can do much worse then setting your properties. It can mess with memory, corrupt data, flood the thread pool, or even easily crash the AppDomain.
The point is, if you don't own the application because you are only providing a class library, you don't need to defend from code running inside the AppDomain where you classes are loaded.
Note: Re. NuGet, I wouldn't be too worried about that. NuGet is sort of a static tool. If I understand correctly, it doesn't do things in runtime such as downloading code and running it. It is only used in design time to download binaries, add references, and possibly add code. I think it's perfectly reasonable to assume that an application owner that uses NuGet to download a package will do his due diligence to ensure that the package is safe. And he has to do it only once, during development.
As the previous answers note, there isn't really much of a difference here.
Malicious code could set a static property, and malicious code could change a configuration file. The latter is probably a bit easier to figure out from the outside, and can be done no matter what way the code is run (it wouldn't have to be .NET, wouldn't have to be run in your app domain, and indeed wouldn't have to be code, should someone gain the ability to change the file manually), so there's a bit of a security advantage in the use of a static property, though it's a rather bogus one considering that we may well have just moved the issue around a bit, since the calling code could very well be using configuration itself to decide what to set the properties to!
There's a third possibility, which is that you have an instance with instance members that set the properties, and it's the calling code that makes that instance static. This might be completely irrelevant to what you are doing, but it can be worth considering cases where someone might want to have your code running with two sets of configuration parameters in the same app domain. As a matter of security, it is much the same as the matter of static members, except that it could affect serialisation concerns.
So, so far there's the disadvantage of configuration files in that they can be attacked by code completely separate to yours, but with the noted caveat that the information might end up in a configuration file somewhere else anyway.
Whichever approach you take, the safety of access comes down to the way that you load in partially-trusted code.
The code should be loaded into its own app domain, and the security on that app domain set appropriately to how well it can be trusted. If at all possible, it shouldn't be your library that is doing so, but left to the calling code to decide upon the policies to be set by any partially-trusted code it loads in. Of course, if it's inherent to your libraries purpose that it loads in partially-trusted code, then it must do so, but generally it should remain agnostic as to whether the code is fully or partially trusted except in demanding certain permissions when appropriate. If it is up to your library to load in this code, then you will need to decide upon the appropriate permissions to give the app domain. Really, this should be the lowest amount of permission where it is still possible to do the job it was loaded in for. This would presumably not include FileIOPermission, hence preventing it from writing to a config file.
Now, whether your library or the calling code has loaded the partially trusted code, you need to consider what permissions are necessary on your exposed classes and their members. This covers the static setter properties, but would still be necessary if you took the config-file approach given that your scenario still involves that there is partially-trusted code accessing your library.
In some cases, the methods won't need any more protection, because they inherently have it due to what they do. For example, if you try to access a file but the calling code does not have permission to do so, then your code will fail with a security exception that will be passed up to the calling code. Indeed, you may have to do the opposite and take measures to allow the partially-trusted code to call your method (if you access a file in a way that is safe because the caller cannot affect which file is accessed or how, you may want to Assert file-access permissions at that point).
In other cases, you may need to add protection because calling code won't do anything that immediately attempts a security-restricted operation but which may cause trusted code to behave in an inappropriate manner. For example, if your code stores paths that are used by later operations, then essentially calling that code allows for file access to happen in a particular way. E.g.:
public string TempFilePath{get;set;}
public void WriteTempData(string data)
{
using(sw = new StreamWriter(TempFilePath, true))
sw.Write(data);
}
Here if malicious code set TempDirPath it could cause a later call by trusted code to WriteTempData to damage an important file by over-writing it. An obvious approach here is to call Demand on an appropriate FileIOPermission object, so that the only code that could set it would be code that was already trusted to write to arbitrary locations anyway (this could of course be combined by both restricting the possible values for TempDirPath and demanding the ability to write within the set of locations that allowed).
You can also demand certain unions of permission, and of course create your own permissions, though using unions of those defined by the framework has an advantage of better fitting in with existing code.
What prevents a malicious component from making changes at runtime?
This depends on the definition of "malicious component". Configuration is really intended to allow changes at runtime.
If you handle this via code (whether static or instance properties, etc), you do have the distinct advantage of controlling the allowable settings directly, as your property setter can control this however you wish. You could also add some form of security, if your application requires it, as you'd control the way this was set.
With a configuration section, your only control would be in reading the values - you couldn't control the writing, but instead would have to validate settings on read.
For sure, it can be changed by underlying classes which provide those abstractions, even in case of being defined as private members.
Think of a security interceptor that provision every request against defined privileges of authenticated or anonymous users.
I generally use Config file and Static variables together. I define static variable as private, and i make only "get" method to expose value. so it is can not be changed out of class.
I create a class to handle configuration implementing "IConfigurationSectionHandler" interface. My implementation is for ASP.NET Web applications.
Step 1: Create a section in web.config file to process later.
<configuration>
<configSections>
<section name="XXXConfiguration" type="Company.XXXConfiguration, Company"/>
...
</configSections>
<XXXConfiguration>
<Variable>Value to set static variable</Variable>
</XXXConfiguration>
...
<configuration>
Step 2: Create a class to handle previous configuration section.
using System;
using System.Collections;
using System.Collections.Specialized;
using System.Xml;
using System.Configuration;
namespace Company{
public class XXXConfiguration : IConfigurationSectionHandler
{
/// <summary>
/// Initializes a new instance of LoggingConfiguration class.
/// </summary>
public XXXConfiguration() {}
private static string _variable;
public static string Variable
{
get {return XXXConfiguration._variable; }
}
public object Create(object parent, object configContext, XmlNode section)
{
// process config section node
XXXConfiguration._variable = section.SelectSingleNode("./Variable").InnerText;
return null;
}
}
}
Step 3: Use GetSection method of System.Configuration.ConfigurationManager at startup of application. In Global.asax
void Application_Start(object sender, EventArgs e)
{
// Code that runs on application startup
System.Configuration.ConfigurationManager.GetSection("LoggingConfiguration");
...
}

Access web.config from separate Class Library?

I'm looking for a good way to achieve the following:
I have a web application (MVC 3), with a separate Class Library that contains the back-end logic of a CMS that I'm making. This CMS uses NHibernate to connect to a database. I want the user to be able to configure the connectionstring (and eventually even the flavour of the database) in their web.config file.
What I'm looking for is a good way to get the connection string from the web.config file, even though the DLL is completely separate. Is this possible? Will I have to pass my connection string to my class library somehow? Or will I be able to access it when the application runs?
If I have to create some code in my web application to pass the connection string to my Class Library, how can I make this code as portable as possible, so I won't have to write it again for my next webapp?
Thanks a lot for any ideas you have.
You can pass in the connection string to the classes in the class library from the web site.
This is a better choice than trying to get the information directly from the configuration file, as otherwise you will have a dependency on the configuration file existing with the exact right key (making testing the class somewhat harder).
See this blog post for arguments against accessing configuration directly (which is very commonly done, but is not best practice).
You can access System.Configuration.ConfigurationManager from your class library. That'll give you access to the AppSettings and ConnectionStrings.
I have exactly the same setup with a FOSS project I'm involved with. It contains everything (even the Controllers and Global.asax.cs) in the 'Core' class library.
There's plenty of valid solutions, the one I opted for was to create a Settings class which is essentially a set of static properties, inside which you have:
public static string ConnectionString
{
get { return ConfigurationManager.ConnectionStrings["MYAPP"].ConnectionString; }
}
Note: make sure your class library has System.Configuration added as a reference.
Inside your Application (the class derived from HttpApplication) you pass the settings across, although there is nothing to stop you tighly coupling the NH setup with the settings class:
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterRoutes(RouteTable.Routes);
SetupNHibernate();
}
public virtual void SetupNHibernate()
{
NHibernateRepository.Current.Configure(RoadkillSettings.DatabaseType, Settings.ConnectionString, false, Settings.CachedEnabled);
}
If this is any use to you, the source is here.
You can use the ConfigurationManager class to access items in your web.config or app.config file. However, in your class library, be sure to take in the key name of any appSettings and/or connectionString settings from the consumer (preferably in the constructor). This avoids the problem of you choosing a key name that the consumer is already using elsewhere.
Since you are using the class library to the MVC web application, it is accessible to the class library also. No additional settings are needed. Even though the class library when built giving a separate dll, it is referenced in the current project. So the connection string will be available to the class library also.
I'd go with something like Autofac to give you some IoC implementation which can store a settings interface for your connection strings. This would allow you to setup the value from the web.config on application start, or to set it within tests to a different value without your Class Library ever having to be coupled to a web.config.
You can add new Existing item from another project to your class library. Then change Build Action to Embedded Resource and Copy to Output Directory to Copy if newer on the Web.config file.
Web.config in another project
<configuration>
<appSettings>
<add key="MyConfigValue" value="Test" />
</appSettings>
</configuration>
Class library test file
var doc = XDocument.Load(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Web.config"));
var myConfigValue = doc.Element("configuration")
.Element("appSettings")
.Elements("add")
.FirstOrDefault(e => e.Attribute("key").Value == "MyConfigValue").Attribute("value").Value;

How do I supply values to an referenced assembly without calling a method it explicitly?

Currently I have a static class that I use as my logging module. I’ve added the class to my visual studio solution. Within the class I’ve specified the name and location of the log file to use.
Which lets me do stuff like this – which I like and want.
Logger.Information(“Page_Load”,”controls loaded correctly”);
I’d like to refactor the code and move the logging functionality into a separately compiled assembly, if I did this I would then need to pass in the log file name and location to save the files too.
However I don’t want to have to supply this information every time I call the ‘Logging’ method, this would be bad...
Logger.Informtaion(“Page_Load”,”controls loaded correctly”,”logfile.txt”,”c:\temp”);
Is there any way I can supply this information without having to specify it within each page or via the method call.
For sure. The simplest thing would be to add a single key to the web.config file, which your class looks at by using the ConfigurationManager.
<configuration>
<appSettings>
<add key="logfile" value="c:\log.txt" />
</appSettings>
<system.web>
...
</system.web>
</configuration>
string logfile = ConfigurationManager.AppSettings["logfile"]
If your logging class is more complex than just one or two configuration options, consider building a ConfigurationSection class to go along with it, which would allow you to create your own section in the web.config.
The configuration approach is good for this type of thing, because then you avoid hard-coding the logfile path into your application code (such as passing it into a static initialization method), which would require a recompile if you needed to change the logging path. However, you should only need to look up the logfile path once, upon creation of your logging class.
I feel obliged to ask if you've investigated using TraceListener and the System.Diagnostics namespace with its built-in logging (as opposed to rolling your own). It's quite extensible.
Have you considered making your logger non-static? Perhaps a singleton? This is the classic example for an appropriate use of the Singleton pattern.
Sure,
Create an initialize method on your static class and pass the file into the initialize mentod. Then call the method at application start.

TDD with Web Config

All great stories they always start with those 4 magical words... I have inherited a system... no wait! that isn't right!
Anyway with my attempt at humour now passed I have not so much been given more I have to support an existing service.
There are many many issues when it comes to using this service, as an example one is to create a record of a person, you need to call 4 different parts of the services.
So, getting together with my Manager we decided that we need to stick another layer on top to add a facade to the common requests, to simplify the number things and the correct order to do them when creating a new site.
My question starts here if anyone wants to avoid the above waffle
So I want to use TDD on the work I am doing, but the service I have inherited (which will become our Data layer) has been strongly coupled with a database connection string located in a specific connetionstring node in the Web.Config.
Problem I have is, to decouple the service from the Config file will take weeks of my time which I do not have.
So I have had to add and App.Config file with the expected node into my Test project.
Is it ok to do this, or should I start investing some time to decouple the database config from the datalayer?
I agree that you should probably look into using Dependency Injection as your working your way through the code to decouple your app from the config, however, I also understand that doing that is not going to be an easy task.
So, to answer your question directly, no, there is nothing wrong with adding a config file to support your tests. This is actually quite common for unit testing legacy systems (legacy being an un-tested system). I have also, when left with no other option, resorted to utilizing reflection to "inject" fake configuration values into the ConfigurationManager in order to test code that is reading configuration values, but this is probably a last resort.
Try using Dependancy Injection to mock up your DataLayer.
In TDD you are not (necessarily) testing your datalayer and database but the BusinessLogic.
Some links:
SO best practices of tdd using c# and rhinomocks
TDD - Rhino Mocks - Part 1 - Introduction
You can use Dependency Injection to "untie" your code from web.config (or app.config for that matter):
http://weblogs.asp.net/psteele/archive/2009/11/23/use-dependency-injection-to-simplify-application-settings.aspx
As you mentioned Dependency Injection is the way to go. You also want to make sure that your consumers of your configuration object are not dependent on your specific configuration implementation such as the ConfigurationManager, ConfigurationSections, etc. To see a full example using custom configuration you can have a look at my blog post on Configuration Ignorance but basically it comprises of.
Your configuration implementation be it using a ConfigurationSection or an XmlReader should be based on an interface that way you can easily mock out your properties and easily change your implementation at a later date.
public BasicConfigurationSection : ConfigurationSection, IBasicConfiguration
{
...
}
To tackle how the the configuration is retried we use a configuration provider, the configuration provider for a particular configuration knows how to retrieve it's configuration
public interface IConfigurationProvider<TConfiguration>
{
TConfiguration GetConfiguration();
}
public class BasicConfigurationProvider : IConfigurationProvider<IBasicConfiguration>
{
public IBasicConfiguration GetConfiguration()
{
return (BasicConfigurationSection)ConfigurationManager.GetSection("Our/Xml/Structure/BasicConfiguration");
}
}
If you are using Windsor you can then wire this up to Windsor's factory facility.
Hope that helps.

Categories