Save Settings in Dependent Dll - c#

I have a Windows Service and a dependent Dll, I chose this way so that Dll can be invoked by any application, Winforms, WPF etc.
Now I am stumped on what is the best practice to Save settings in the Dll, I used User Settings in the dll and Saved them from calling App.
public class Preferences
{
public static string IPAddress
{
get { return Settings.Default.IPAddress; }
set { Settings.Default.IPAddress = value; }
}
}
and then in my service/Winforms Code, I wrote
Preferences.IPAddress = "XX.XX.XX.XX"
Someone told me this is not how you should do it . I wanted to know is this not the correct approach

Related

Winform app: Compiled App.Config-like file?

I would like to know if there is some kind of built-in compiled "App.Config" file?
The goal is to be able to have one of our library which can have some of its default values overriden when being used in some client application.
Thoses DLL are loaded dynamically, so I cannot just give a parameter in the constructor.
I don't want to use the App.config file because the user can edit those values(otherwise it would have been just fine).
There are several different ways to solve this.
If you like the idea of config-files, but do not want to have it accessible by end users in the compiled application, perhaps you can create your own settings-file in a format that suits your needs, and include it as an embedded resource?
An upside of this would be that you can access it as a regular XML or config file or whatever in Visual Studio, while it will be hidden from the end user. Personally I think I would prefer this to using special code / classes to store config-data.
To include a file as an embedded resource, include it into one of your Visual Studio projects, right click the included file and select Properties. Now under Build Action, select Embedded Resource. When you build your project now, the file will be included internally in the produced .dll-file.
I'm sure you'll be able to find lot's of info about how to access an embedded resource from code. As an example, there are some useful examples in this SO question. Note especially this answer, which also mentions an alternative way to include a resource.
Expanding on my comment... you could just make an interface for a settings class with hardcoded values, and then make different implementations of that interface. To actually change which one to use, all you'd need to do is comment/uncomment the line that instantiates an object into your settings variable before you build the dll:
public class MainDllProject
{
ISettings m_Settings;
public MainDllProject()
{
// Change this before compiling
this.m_Settings = new DebugSettings();
//this.m_Settings = new DeploySettings();
// use settings from the settings class
String setting1 = this.m_Settings.Setting1
Int32 setting2 = this.m_Settings.Setting2
//...
}
}
public interface ISettings
{
String Setting1 { get; }
Int32 Setting2 { get; }
}
public class DebugSettings: ISettings
{
public String Setting1
{ get { return "data_debug";} }
public Int32 Setting2
{ get { return 2;} }
}
public class DeploySettings: ISettings
{
public String Setting1
{ get { return "data_deploy";} }
public Int32 Setting2
{ get { return 1;} }
}
On finding "a built-in way of solving this", as you said, maybe this will be useful for you...
You can actually use the Visual Studio build configuration manager to build with different settings. Using the #If directives, you can automatically make it select which lines of code to use based on the configuration. A simple example based on the default debug configuration, which adds the "DEBUG=True" variable automatically:
public MainDllProject()
{
#If DEBUG Then
this.m_Settings = new DebugSettings();
#ElseIf
this.m_Settings = new DeploySettings();
#End if
}
You can actually make your own custom-named variables to check on just like that DEBUG one: after making a configuration, open the Project properties window, go to the Compile tab, select that specific configuration in the dropdown, and then at the bottom select "Advanced Compile Options". In there is a line "Custom constants" in which you can add such variables. For simple if-statements, you can just make a boolean like "CLIENTDEPLOY=True", and then you can use #If CLIENTDEPLOY Then in your code.

Reading user settings from another application

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.

App.config multi-project access strategies

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.

Sharing settings between applications

I have multiple .NET assemblies that all need to share common user settings, such as preferences, user names, etc. One is a WPF application, another is a console application, and the third is an Office Add-in. All of these settings are user-scope.
Only the WPF application needs to be able to change settings. The rest just read them.
Ideally, I'd like to use the .NET configuration framework. I'm not sure how to do this though. If I add Settings to the WPF application, how can the other applications find the user.config file?
Is it just easier to create a class library and use IsolatedFileStorage and serialize my settings?
Any advice would be greatly appreciated.
You can implement your custom settings class, inheriting ApplicationSettingsBase. As a good start, you can add the default User Settings file to a sample project (Right click on the project -> Properties -> Settings -> This project does not contain a default settings file. Click here to create one.). Add a user-scoped setting and investigate the structure of the designer-generated Settings.Designer.cs file:
namespace ConsoleApplication1.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default {
get {
return defaultInstance;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("John Doe")]
public string Name {
get {
return ((string)(this["Name"]));
}
set {
this["Name"] = value;
}
}
}
}
In your custom implementation, you will not be limited to the designer-generated access modifiers, so you can implement the Settings class as internal with internal setters, visible only to the needed assemblies, or whatever fits your needs.
Of course, you can always implement your custom serialize/deserialize mechanism, but you will lose the funcionality provided by ApplicationSettingsBase's Updgrade, Reload, and Reset methods. If you don't need any of these, this could be the cleaner approach.
I would recommend you to create service to provide and update user info and or preferences. It will be better architecture, cleaner solution and it will be easier to maintain and extend.

Change Properties.settings for a .net deployed application

Hi All,
I have two .net applications, these applications want to talk to each other, I made a setting in the first project as follows
[CompilerGeneratedAttribute()]
[GeneratedCodeAttribute("SettingsSingleFileGenerator", "9.0.0.0")]
public sealed partial class Settings :ApplicationSettingsBase
{
[UserScopedSettingAttribute()]
[DebuggerNonUserCodeAttribute()]
[DefaultSettingValueAttribute("False")]
public bool BeginWorking {
get {
return ((bool)(this["BeginWorking"]));
}
set {
this["BeginWorking"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("False")]
public bool Result {
get {
return ((bool)(this["Result"]));
}
set {
this["Result"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("False")]
public bool Completed{
get {
return ((bool)(this["Completed"]));
}
set {
this["Completed"] = value;
}
}
}
the second project may set the BeginWorking setting for the first project in order to tell it to work, and waits for the Completed setting to be set and get the result from the Result setting.
Is that possible and how??
I feel it may be not easy to answer but excuse me I'm get unable to think more.
Thanks All
User level app settings are isolated in a subdirectory of AppData. One app cannot find the settings of another app. Just use a plain file.
I've not used it but .NET Remoting might be more suitable to your needs see MSDN link text
Settings are persisted to a configuration file that is saved on disk. As far as I know the default place for this is in the user's application directory (%appdata%). Since this file is persisted to disk your other application would need to be able to read and write to this same file.
If both applications are reading and writing to the same file then you should be able to do what you want to do.

Categories

Resources