Background:
I have a win app and a web app and a
shared class library.
In my class lib I have some static
methods for SQL queries which pick up
my SQL connection string
I store my SQL connection string in a
Session variable since it is set at
log in time where it is determined
which database to use.
My class lib cannot access my session
variables (yes, of course I can use
HttpContext.Current..., but that wont
work in my winapp)
Solution?
I envision a sort of solution where I have a class for my current user/context and when creating it I inject the preferred behaviour, something like this:
UserContex current = new UserContext();
current.SessionHandler = new AspNetSessionHandler();
However, I would like a static class which I could user without having to pass it along all the time and then it would get it's variables either from the session if used in a web app or from somewhere else (I'm not a winapp developer) if used in a winform.
I will try to conjure up this kind of thing, but it would be great if I found an already working solution and that's why I call on the shared collective madness of you guys
Csla contains a similar setup using a static ApplicationContext class which is discussed in Rockford Lhotka's book Expert C# Business Objects...To deal with the connection string issue I would suggest creating a DataConnection class that returns a static connection string from the config file that way it doesn't matter if the connection string is coming from the Web.config or the App.config
public class DataConnection
{
public static string NameOfConnection
{
get
{
return ConfigurationManager.ConnectionStrings["NameOfConnection"].ConnectionString;
}
}
}
Related
I've got a Windows Form program that creates a Config object which contains various configuration variables used by my program.
Within the main form, it contains a button to open a new configuration form, where it passes the Config object as a reference -
FormConfig button = new FormConfig(ref config);
button.ShowDialog();
Now in the FormConfig class, I can access the Config object within the main constructor
public FormConfig(ref Config config)
{
InitializeComponent();
// can access config.xyz OK here
}
However within the new form, I've got a button that calls another function that needs to access the reference Config object, however I'm struggling to find a clean way to do so.
I can create another Config object as part of the FormConfig class, and then copy the referenced Config to it in the main constructor, however then the original config object doesn't get updated.
How can I achieve this?
PS apologies in advance if this is already answered, but my searches have so far failed to find a solution, possibly because I'm not sure what the correct search terms should be.
And the solution thanks to #cmos, is to declare the Config class as static, which negates the need to use any referencing or passing objects between classes/functions -
public static class Config
{
public static bool SettingA = true;
}
Which means I can access and modify the Config object from anywhere within the same namespace with the following code, without needing to have a class instance -
Config.SettingA
Thanks to all those who helped point me in the right direction.
I have a windows application that writes user settings using the method described here:
http://msdn.microsoft.com/en-us/library/bb397755(v=vs.110).aspx
These settings are saved to a file in the users directory e.g:
c:\users\{you name}\Local\{Company}\{product}\user.config
I need to access these settings in a companion console application. Is this possible, at the moment the settings return null when I try to access them from the console application.
The code itself will look something like this:
To save the settings in App1:
namespace Application1{
public class DemoSave{
public void DoWork(){
Application1.Properties.Settings.Default.CustomSettings.Title ="someValue";
Application1.Properties.Settings.Default.Save();
}
}
}
To read the settings in another app:
namespace Application2{
public class Demo{
public void DoWork(){
var title = Application1.Properties.Settings.Default.CustomSettings.Title;
}
}
}
In Application2 the Application1.Properties.Settings.Default.CustomSettings property is null.
Last time I did something similar, I had two projects in a solution (a windows service and a wpf application), and I had to reference the WPF app in the Win Service project to access it's settings (I assume you're talking about Namespace.Properties.Settings). It seems to have worked fine for me. In this case i had to set the access modifier on the settings to public though. I'm not sure if this is the best way, but it worked for me for something very small and insignificant.
Are you even sure your pointing at the right place when you modifies/read the settings files.
Because that might be why it doesn't work.
My current solution has 3 project with 2 app.config (one for common settings and another for service settings). As of now I'm simply creating static classes to act as a mediator to access values. I do this so I don't have to write ConfigurationManager.AppSettings["SomeKey"] everywhere. This works fine until you want to access an app.config file from a different project.
Here is what I'm currently doing (all properties omitted for brevity).
public class ServiceConfiguration
{
public static readonly string SyncEvery = ConfigurationManager.AppSettings["SyncEveryMinutes"];
}
How can I access an app.config file located in another project? I thought perhaps setting VS to copy the file to the output directory would do the trick however my configuration object is still null.
I can't imaging many good reasons to read another app's configuration in the first place, it just opens a can of worms that isn't worth dealing with.
Expose a class that exposes the project's configured values as properties, and access them from a consuming class.
public class FirstProjectClass
{
public static int SyncEveryMinutes
{
get { return (int)ConfigurationManager.AppSetting["SyncEveryMinutes"] };
}
}
public class SecondProjectClass
{
public void ShowConfigedValue()
{
Console.Writeline("Syncing every {0} minutes", FirstProjectClass.SyncEveryMinutes);
}
}
if you've got complex configuration requirements you can also look into custom configuration sections
ConfigurationManager.OpenExeConfiguration can be helpfull:
http://msdn.microsoft.com/en-us/library/system.configuration.configurationmanager.openexeconfiguration.aspx
Also: what Jason said - it is usually a bad idea.
Currently in my personal website I'm building I'm using a global static Config class to hold everything configurable I might need to change that is semi-global. So right now it looks about like this:
public static class Config
{
public static string ConnectionString = "mongodb://localhost";
//more configuration options..
public static MongoDB.Driver.MongoDatabase GetDB(){
MongoServer server = MongoServer.Create(Config.ConnectionString);
MongoDatabase db = server.GetDatabase(Config.Database);
return db;
}
public static Markdown GetMarkdown(){
var options=new MarkdownOptions(){
AutoHyperlink=true,
AutoNewlines=false,
EmptyElementSuffix=" />",
LinkEmails=false,
StrictBoldItalic=true
};
var m=new Markdown(options);
return m;
}
}
Is using a global config class like this an anti-pattern of some sort? Also, I prefer for my connection strings to be outside of web.config. I like my web.config to be as minimal as possible.
Well of the 3 members only 1 is really config, the other two are utility really.
Having configuration in compiled code is really a pain to maintain if those configs need to be changed, since it requires a rebuild, that is really the reason for configuration files.
I do things similar to this but not for settings like connection strings. If the connection string needs to change, you need to update and rebuild your project. If you stored the connection string in your web.config, a simple update allow your app to immediately use the new setting (no recompile).
Earlz ,
Regarding your second question you can do something like this, there is no need to have all the connections or configs in web.config. You can have a separate config file and point that in the web.config file as below
<connectionStrings configSource="config\yourpath\connectionStrings.config"/>
Regarding the first question , write a common method which get the values. Load all the values to a constants file and write a helper class to get those values
The anti-pattern is that you have GetMarkdown and ConnectionString together in the same class because they are both static, yet they really have no functional relationship. GetMarkdown and GetDB both look like factory methods and they should probably be in their own classes.
The Single Responsibility Principle says you should group things together that are likely change for the same reason. It's unlikely that your database connection and markdown config will change at the same time or for the same reason.
We moved our config settings to the database. Makes it easier when moving from Dev to QA to Prod. The blog entry is here.
Related to this, we put the connection string off to the side in a WebEnvironment.config. So now we can promote our code with web.config changes and not worry about the connection string. That blog post is here.
I set up various global parameters in Global.asax, as such:
Application["PagePolicies"] = "~/Lab/Policies.aspx";
Application["PageShare"] = "/Share.aspx";
Application["FileSearchQueries"] = Server.MapPath("~/Resources/SearchQueries.xml");
...
I have no problem accessing these variables form .ascx.cs or .aspx.cs file -- ie. files that are part of the Web content. However, I can't seem to access 'Application' from basic class objects (ie. standalone .cs files). I read somewhere to use a slight variations in .cs files, as follows, but it always comes throws an exception when in use:
String file = (String)System.Web.HttpContext.Current.Application["FileSearchQueries"];
While it's true that you can use HttpContext.Current from any class you must still be processing an HTTP request when you call it - otherwise there is no current context. I presume that's the reason you're getting an exception, but posting the actual exception would help clarify matters.
to share your variable across app, and to be able to access it from standalone class, you can use static variable of a class, instead of using HttpApplication variable.
public MyClass{
public static int sharedVar;
}
//and than you can write somwhere in app:
MyClass.sharedVar= 1;
//and in another location:
int localVar = MyClass.sharedVar;