I am setting up a .net project that is called to generate other webpages. Basically a true CODE BEHIND page. How do I go about making a connection on a Class Library File, when there is no webconfig file present/available?
In this case, I would create a 'Base Page' that derives from System.Web.UI.Page. On this page, you would create a property called 'ConnectionString'. You will have all of your web pages you create inherit from this page.
Example:
public partial class BasePage : System.Web.UI.Page
{
protected string ConnectionString
{
get
{
return System.Configuration.ConfigurationSettings.AppSettings["MyConnectionString"];
}
}
}
And in your web.config
<appSettings>
<!-- Connection String -->
<add key="MyConnectionString" value="Data Source=myServerAddress;Initial Catalog=myDataBase;User Id=myUsername;Password=myPassword;"/>
</appSettings>
Now you can have a web.config file with a connection string that is easily readable. And you can store this 'Base Page' in your class library, no problem. As long as your web pages inheriting from it are using the web.config file with the connection string.
After that, it's a simple matter of connecting using that string. You can do this in a variety of ways, either in your web pages, or in separate classes (I recommend separate classes). In this case, if you had a separate class, you would need to pass in the ConnectionString property to your connecting functions:
public void ExecuteQuery(string connectionString, string sql)
{
using (System.Data.SqlClient.SqlConnection theConnection = new System.Data.SqlClient.SqlConnection(connectionString))
using (System.Data.SqlClient.SqlCommand theCommand = new System.Data.SqlClient.SqlCommand(sql, theConnection))
{
theConnection.Open();
theCommand.CommandType = CommandType.Text;
theCommand.ExecuteNonQuery();
}
}
or you can create a function that does not take a connection string parameter, and just reads from the web.config file. It sounds like you may want to put your connecting and data access code in a class library for good separation of data and content. Hope this helps!
There are several ways to solve this:
1) If you're class library is really going to generate web pages, then it will probably be deployed on the server with the web.config and so can use properties of the web.config file. If you don't want to use the ConnectionString part, then you can just make an appSetting with the connection string.
The benefits of doing this are that it's easy to change or have different connection strings for different environments (testing, deployment, etc.). And if you decide to use the class library in another kind of app, you can use the app.config file with the same setting.
Depending on the type of database, you'll be using the System.Data and possibly some of the sub-namespaces to make this work.
2) You can hard code the connection string into the code. Ugly, but workable in a pinch.
3) You could use an entity framework to help you out and cut down on the work that you have to do.
System.Data namespace. If using SQL Server, a SQLConnection object.
I use the Application Data Blocks for data access b/c I think it is a time saver. That framework is great for SQL Server access.
Will your library be called from an ASP.net site? If so, you can still use the same methods for accessing the application settings. Otherwise, you may need some kind of app.config for whatever front end you're putting on this.
Also, you don't need a connecting in your configuration in most class libraries, unless you are using an ORM which needs to use it to pick up some info. The calling application's configuration will be used when you are running the thing, so it will pick up the configuration out of the web.config or whatever.
Related
In an MVC web application I want to override connection strings based on the development machine I'm using. I can use Web.config transformations, but I also need to override connection strings in various non-web config files. I can use the SlowCheetah extension, but then I will end up creating the same transformation for every project that accesses the database. This is a hassle to maintain when the project becomes bigger and has more developers.
What I would like to do is modify the way Entity Framework or ASP.NET look for connection strings, adding a class of my own that looks for connection strings, and only implement the transformation logic once. I would hopefully use Ninject to inject it only when relevant.
Is there such an "IConnectionStringProvider" interface I can implement and register, and automagically have ASP.NET and EF use it?
EDIT. I have found this, but it seems real nasty. If there's no cleaner way, I'll just use multiple identical configuration translations, and maybe let the source control system duplicate them properly.
You can tell Entity Framework to use a different connection string - it doesn't have to use the default one in web.config.
Here is an example: http://www.codeproject.com/Tips/234677/Set-the-connection-string-for-Entity-Framework-at
Here is another: http://msdn.microsoft.com/en-us/library/bb738533.aspx
It's up to you how you architect the rest of it.
Personally I use an app setting in web.config to tell my code which connection string to use for a particular part of the system, e.g.
var connectionStringNameForMyFeature = ConfigurationManager.AppSettings["connectionStringNameForMyFeature"];
myFeature.ConnectionString = ConfigurationManager.ConnectionStrings[connectionStringName];
Do you see any benefit in injecting the database connnection string from the Global.asax.cs
class in ASP.NET MVC compared to the method in reading the connection string from a BaseDataProvider class accessing the app.config file?
I'd prefer to inject any objects needed using constructor injection (whenever possible).
One small advantage I see is transparency regarding a class's dependencies.
For example, if you try to instantiate a class in a test harness (while doing integration testing):
in the first case (constructor injection) you immediately see that it needs a connection string and provide one
in the second case you instantiate the class (perhaps using a default constructor) and after some trial & error discover that it depends on the ConnectionString property being set
Update:
Another advantage of the constructor injection approach is that it decouples the class itself from the mechanism of getting the connection string from the app.config.
This could enable in the future scenarios that you don't even think about right now.
For example, in a project I currently work on I have a component that has db access and I have reused it in several contexts. In some of them it uses a standard connection string coming from the config file, while in others I have another component that decides which connection string to use based on some conditions.
If you go for the second approach, you'll need to change the code in order to support such a functionality.
I usually take a hybrid approach such that my BaseDataProvider class has an empty constructor which defaults to whatever is stored in the config, but is overriden to accept a connString for cases where I need a connection other than the default.
Then my Global.asax class contains the necessary logic to determine what connection string they might need in a given situation. For example, say you have your web application deployed internationally on servers all over the world, you'd want to connect to the nearest available db server to avoid latency issues. So on user login, I would figure out where my user was and then set them up with the appropriate connection
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;
So normally I just put my sql connection string in my asp.net web.config and reference it whenever I need to open a database connection, however this leaves me with referencing it all over my project. This also exposes my sql connection username and password in my web.config if it isn't encoded.
What are you best practices as far as keeping the connection methods in a class or class library? I saw a php tutorial that did this really well (but I can't find it again) and allowed for re-usability.
I would always keep the connection string in the web.config since the servers/database connections can always change, even if it's not common.
To make it more comfortable to view in code you can always add something like this :
String m_Connection = ConfigurationManager.AppSettings["MyConnectionString"];
and then just reference m_Connection everywhere.
I would also always encrypt the connection string using an EncryptionProvider.
Great MSDN article : How To: Encrypt Configuration Sections in ASP.NET 2.0 Using DPAPI
I agree with #gillyb. In most cases the web.config is the place for the connection string(s). The other common alternative is a spring.Net config file if you make heavy use of dependedncy injection. The end result is the same except that the site will not rebuild if you change the Spring.config file, whereas it will if you change web.config.
We have a website that we would like to extrapolate user controls from and put them into an assembly of their own. This is so we can more easily reuse these controls in other similar projects. I think we can do this fairly easily by creating a new class library project, moving the .ascx and .ascx.cs files over to this project, adding the appropriate .net assembly references, and modifying our project's references to these user controls to pull them from the library.
The problem I'm foreseeing at this point is that these controls are heavily dependent on a certain database schema. Historically, we have always kept our connection strings in the web.config, and have been using LINQ to SQL for our database management, so I am having trouble conjuring up a "best-practices" way to share database connection information in the web.config with the assembly. The only way I could think of doing it is to add a ConnectionString property to each of my user controls, and on Page_Load, set the ConnectionString property (which will in turn create an instance of the data context using that connection string). However, I was hoping to instead accomplish one of the following:
Somehow have the assembly pull the connection string directly from the web.config. Since the assembly is not a web application, I obviously can't just call ConfigurationManager.ConnectionStrings["connection"]. Is this possible?
Less likely, but figure out a way to set the connection string once on application start and have each instance of my user controls somehow reuse this. I would think there would be a way to cache this value for reuse by the assembly, but I can't think of a way to do it.
Any suggestions are greatly appreciated.
The controls will use whatever connection strings are included in the config of the calling application. There is no need for a seperate config.
I obviously can't just call ConfigurationManager.ConnectionStrings["connection"]. Is this possible??
Yes!
Calls to System.Configuration.ConfigurationManager.ConnectionStrings will return results from the application's web.config even if the calling code is placed in it's own assembly. Remember: it's not assembly.config, it's web.config.
If your user controls are expecting a connection string named "MyDatabase" then every web application that they're used in will need a MyDatabase connection string defined in its web.config.