I am using CommandLine Parser Library to parse command line arguments within an application.
There are some options that will in most cases be the same every time a user runs the application. Usually, I use the DefaultValue attribute so that if the user does not provide a value a default one will be used.
[Option('a', "address", DefaultValue = "http://me.com", Required = false, HelpText = "Address of server.")]
public string Address{ get; set; }
The issue I am facing is that the default value is specific for a given deployment and needs to be configured after deployment. I would like the user/administrator to be able to set the default value of these options using a configuration file.
Does anyone know how to change the default value for an option at run time? Then when starting the application I can load the configuration file and set the default values accordingly.
For the benefit of anyone else looking for this, I was facing the same issue today, and I realised that Options work fine with C# 6 Auto Property Initializers.
[Option]
public string MyProperty { get; set; } = Properties.Settings.Default.MySetting;
No doubt in C# 5 and earlier you could achieve the same thing with a private backing property.
I would create the properties as Application Settings, then allow the user to override them with command line arguments and calculate the resulting values at runtime.
This way you have compiled default values, possibilities for the user to override with custom defaults in the config file and a way to set one-time overrides at startup.
Related
When defining the default value, what is the difference between
[DefaultValue("member")]
public string Role { get; set; }
and
public string Role { get; set; } = "member";
The first is an attribute which can be useful for meta-programming. For example, you might want to remember what the default value is if someone clears an input. It has nothing to do with the C# language itself. It does not modify the value of Role.
The second actually sets the property's value to 'member' in memory.
From the documentation:
A DefaultValueAttribute will not cause a member to be automatically initialized with the attribute's value. You must set the initial value in your code.
In other words, your first example helps tools (like the Windows Forms Designer) to know what the intended default value for a property is. But it does nothing at run-time.
If you want a property to be assigned a default value at run-time, you have to do it yourself, as in the second example you show.
I am building a customizable setup application with WiX, having started with this tutorial:
http://bryanpjohnston.com/2012/09/28/custom-wix-managed-bootstrapper-application/
The setup needs to be customizable, so I need to set some Variables from inside my MainViewModel this is an example:
var customProductName = "The Custom Product";
this.Bootstrapper.Engine.StringVariables["WixBundleName"] = theCustomProduct;
This works how expected. However, I cannot set the Variable WixBundleManufacturer. I get a System.ArgumentException: Value does not fall within the expected range.
Is it somehow possible to set the manufacturer value from inside my view model at runtime?
No, the WixBundleManufacturer is read-only variable set from the authored Bundle element Manufacturer attribute. You could open a feature request.
The feature request was implemented in v3.10.0.1719. The variable is now writable like any other Burn variable.
Here's what I want to do:
Have an application-scoped Settings setting whose value is an array of a custom type
Have the array of the custom type serialized to XML as opposed to a string
Have the serialized value of my setting saved in app.config.
So far this is eluding me.
I have a custom type:
[TypeConverter(typeof(ServiceConfigurationConverter))]
[Serializable]
public class ServiceConfiguration
{
public string Name { get; set; }
public string Url { get; set; }
// more
}
It has a custom TypeConverter that converts it back and forth from a string. I wrote it that way because the examples I found were all for converting to strings, and because I'd be willing to serialize to a string if it meant that my values were being saved to app.config. But as we will see, they aren't.
If I indicate (through editing the Settings.settings file directly) that the type of this setting is MyNamespace.ServiceConfiguration[], I can enter XML manually to represent the array. (I got the XML by writing a test that programmatically built the array and then serialized it using XmlSerializer.) But, while this XML gets set in Settings.designer.cs as the default value for the setting, it doesn't get saved to app.config.
And that's problematic, because I want people to be able to see the property values in XML form in the the app.config, and be able to change them if need be. If it's not written and read from the app.config, it's not run-time configurable.
If I manually create an entry in app.config, under applicationSettings, and enter in my serialized array as the setting's value, the settings designer asks me if I want to update the settings file value, and does so -- but removes the entry I put in under applicationSettings.
I'd be willing to consider writing some kind of designer for my custom type, if necessary, but I don't know what kind of designer that would be.
(I know that if I just changed the property type to "string" I could save the serialized XML as a string and avoid this whole problem. But what I want is a property whose type is my custom type, not one I'd have to reconstitute.)
Can anyone tell me how to achieve the three goals at the top of this post with a custom type?
Many thanks.
I've got a typical C# automatic property. How can I apply WebUtility.HtmlDecode() when I've only got a get; set;?
UPDATE:
Ok, dumb mistake of the day. I had a weird issue where my web.config db connection string was pointed to the right server but for some reason since I had 2 instances (one sql 2008 and 2012) it was still picking up the instance of that DB in 2008 which had the encoding still there. I had fixed the encoding issue by just decoding the Title via a unit test I created in the 2012 DB which in this case this whole fing post was unecessary in stack because the ultimate problem was it was reading from the old DB (messing me up).
Anyway I had already fixed this, finally got rid of the 2008 copy and now it's reading it fine after my fix:
[Test]
public void CleanAllPostEntries_DecodeHTML_DecodeWasSuccessful()
{
// Arrange
// Act
IEnumerable<Entry> posts = PostCRUD.GetAllPosts();
foreach (Entry post in posts)
{
post.Title = WebUtility.HtmlDecode(post.Title);
post.Body = WebUtility.HtmlDecode(post.Body);
post.MetaTitle = WebUtility.HtmlDecode(post.MetaTitle);
PostCRUD.UpdatePost(post);
//System.Diagnostics.Debug.WriteLine("id: " + post.Id);
//System.Diagnostics.Debug.WriteLine("title: " + WebUtility.HtmlDecode(post.Title));
//System.Diagnostics.Debug.WriteLine("body: " + WebUtility.HtmlDecode(post.Body));
}
//Assert
// TODO: add asserts
}
So I don't think I need the decode afterall..I already did it!
you can't, I think. The only way to do is to have a separate method that formats the value and assign it to the property, ex
private string SamplePropery {get; set;}
private string FormatMethod(string value) {}
private void SampleExecute()
{
// format and set to property
SampleProperty = FormatMethod("hello world");
// get property and format the value
string _value = FormatMethod(SampleProperty);
}
The value of a property shouldn't change once set. It's supposed to return the same value you set. That's why it's called a property. Call HtmlDecode before you set the property value.
Should other people work with your classes and not have access to your source they wouldn't imagine you're doing any kind of processing when setting the property value.
You really don't want to do HTML encoding/decoding via properties, although you could if you wanted to. There are several problems with this:
You'll be taking that encoding/decoding hit on every single access of the property, be it reading or writing.
The HTML encode/decode is a "lossy" conversion and you only want to do it exactly once per string; you don't want to be constantly encoding and decoding and re-encoding the same string when you're tossing it around on multiple properties, you'll start to lose information that way.
The HTML encoding of the content is not a property of the object you're storing it with, it is a property of the content itself.
What you really want to do is use a stronger type that represents the HTML-encoded string.
The .NET 4.0 framework includes a System.Web.HtmlString type which you should use for this purpose. In fact, use the System.Web.IHtmlString interface if you wish to remain general.
You can't do it automatically with the magic getters and setters. You need to create your own private property and use it as the backing store for your public properties.
Example:
private string _Item;
public string Item
{
get
{
return _Item;
}
set
{
_Item = WebUtility.HtmlDecode(value);
}
}
However, other answers to this question are correct that this is probably a bad idea. For example, if your code is ever used outside of an HTML application, you will have to HTML-encode all text before you set this property.
I have an Windows Forms application VS 2008 - C#, that uses app.config.
In execution time, in Menu option of my application, I want editing values of app.config, save it and restart application.
any sample source code, any good patterns and practices ??
edit:
in MSDN Forums, Jean Paul VA:
Create an test windows forms application and add an app.config into it.
Add reference to System.confguration
Add a key named "font" in appSettings with value "Verdana"
Place a button on form and on click of it add the modification code.
System.Configuration.Configuration configuration = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
configuration.AppSettings.Settings.Remove("font");
configuration.AppSettings.Settings.Add("font", "Calibri");
configuration.Save(ConfigurationSaveMode.Modified);
ConfigurationManager.RefreshSection("appSettings");
what you think about it ?
I don't think you can actually write to the configuration file at runtime - it may well be read-only, however, there may be a way around this by re-writing the file (with proper alterations as required) and essentially replacing the existing one, then, further, restarting the application to load the new values (I highly doubt this is desirable and personally would not try to instrument this malarkey).
You may also just consider storing application settings in the settings file which are easily manipulated in this way.
To use settings, first let's assume you have a Settings.settings file (if not then create one: Add Item->Settings File), then we have a setting configured named MyUnicornsName; In order to make a change and persist it you can simply do as follows:
Settings.Default.MyUnicornsName = "Lucifers Spawn";
Settings.Default.Save();
Similarly, to read a setting:
ATextDisplayControl.Text = Settings.Default.MyUnicornsName
In case you don't know, Visual Studio will open the settings editor when you open/double click the settings file in the IDE; using this interface you can add and edit your initial settings and their values, and string is not the only supported value, all primitives can be used, and, as far as I know, any serializable value too.
Is there any reason you can't use the usual auto-gen'd Properties.Settings to store the changing data in a settings file instead? One great thing is that you know what you're changing so you don't even have to restart the application!
Using Settings in C#
Runtime access of settings is as easy as:
this.BackColor = Properties.Settings.Default.myColor;
(There is no good pattern for modifing app.config itself simply b/c it's designed to be readonly in that context, with expert-user settings.)
Use the Project->Properties->Settings for these kinds of things.
well actually the Properties in the App.config are ReadOnly so u cant do it.
But there's a trick............................
In the Settings.cs file create a Function or method that is public so that it can be available with Properties.settings
and write the following code..
public void ChangeProperty(string propertyname, string value)
{
this[propertyname] = value;
}
remember to pass the exact string of the property name to the method. or better create a Writeonly Property for the setting.
update
here is a code for setting as a property, i am taking a connection string as an example, bet it can be anything. remember the property stored is of Object type so you can create property specific to that..
public string MyCustomConnectionstring
{
set
{
//replace the string with your connection string otr what ever setting you want to change
this["myConnectionString"] = value;
}
}
Now you can easily use this Property to change the ConnectionString at run time...