In my .net 4 solution, i have two different projects- an web application project and a class library project.
In web application project, database connection string is in web.config file. I would like to access that connection string from class library project. Is it possible? if yes, how?
If there is any better approach to get connection string, please let me know.
To access it from your class library add a reference to System.Configuration then use System.Confinguration.ConfigurationManager.ConnectionStrings.
It's not ideal to read this from a class library. After all, can you say that your class library will always be consumed by something with a configuration file? Certainly not if you share it with other developers, especially of different platforms.
Consider:
IoC - use dependency injection to provide a dependency that contains configuration settings. These would be populated by the consuming library (web app).
Pass the settings to the class library when consuming elements that depend on them.
e.g.:
public class MyLibraryContainer
{
private string _connectionString;
public MyLibraryContainer(string connectionString)
{
_connectionString = connectionString;
}
}
Related
I have in my application layers: Web, DAL and BLL.
Where should I place SettingsProvider class (to get values from web.config)? I think it should be inside DAL project. Am I right?
public class SettingsProvider : ISettingsProvider
{
public string UploadImagesPath
{
get { return ConfigurationManager.AppSettings["UploadImagesPath"]; }
}
..............
}
I don't agree that there is a right layer for you to put that class since you reading values from the config file based on keys provided and it can be needed by one or all of the layers. In the case of all layers using this class, you can as well setup a common Class Library project and reference it in layers where it is needed.
Since settings are specific to Web application (because they are defined in Web.config) I think you should put it in Web application and somehow "send" them to BLL or DAL, wherever appropriate. And since you already have an ISettingsProvider interface defined, you could make a use of some IoC container and registering this interface on Web's bootstrap method (or sth like that). Or just send your ISettingsProvider (maybe static variable) arround into DAL and BLL from Web application.
I know EWL has support for services, but I'm not sure what is different about them or what steps I have to take to create one.
Also, is it possible to manually deploy an EWL service in the same manner as a conventional service, or do I have to use the deployment utility?
EWL services give you a simple programming model, with only three places you can put your logic: the Init, CleanUp, and Tick methods. Besides deciding how to divide your logic among these methods, no thinking is required. There is also no flexibility beyond these three methods, so if your problem doesn't neatly fit into this model, don't use an EWL service.
To create an EWL service inside an existing EWL solution:
Add a Windows Service project to your solution. Name it "Windows Service" or anything else. Set it to use the EWL NuGet package, just like the other projects in your solution.
In Library/Configuration/General.xml, add a section like this beneath <WebApplications>:
<WindowsServices>
<Service>
<Name>YOUR-SERVICE-PROJECT-NAME</Name>
<NamespaceAndAssemblyName>YOUR-SERVICE-PROJECT-NAMESPACE</NamespaceAndAssemblyName>
</Service>
</WindowsServices>
Update dependent logic.
Show hidden files in your service project, and add Generated Code/ISU.cs.
Add a Program.cs file to the project, containing this class:
internal partial class Program {
static partial void initGlobalLogic( ref SystemLogic globalLogic ) {
globalLogic = new GlobalLogic();
}
}
Add a CAMEL-CASED-SERVICE-PROJECT-NAME.cs file to the project, containing a class similar to:
internal partial class CAMEL-CASED-SERVICE-PROJECT-NAME {
string WindowsServiceBase.Description { get { return "..."; } }
void WindowsServiceBase.Init() {}
void WindowsServiceBase.CleanUp() {}
void WindowsServiceBase.Tick() {}
}
Remove any boilerplate files in your project that seem unnecessary.
I believe you can install EWL services manually. Just do a build and do whatever you need to with the files in the bin directory.
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;
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
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.
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.
I can store the connection string in the machine.config, but once again not sure about all the implications....
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.