create property for encapsulation - c#

when for Perperty created a private field,Do it is compulsor??
and when do not created?
enter code here
namespace ApplicationStartSample
{
public class Configuration
{
private Configuration()
{
}
private static Configuration _Current;
public static Configuration Current
{
get
{
if (_Current == null)
_Current = new Configuration();
return _Current;
}
}
private const string Path = "Software\\MFT\\Registry Sample";
public bool EnableWelcomeMessage
{
get
{
return bool.Parse(Read("EnableWelcomeMessage", "false"));
}
set
{
Write("EnableWelcomeMessage", value.ToString());
}
}
public string Company //why do not create private field?
{
get
{
return Read("Company", "MFT");
}
set
{
Write("Company", value);
}
}
public string WelcomeMessage
{
get
{
return Read("WelcomeMessage", string.Empty);
}
set
{
Write("WelcomeMessage", value);
}
}
public string Server
{
get
{
return Read("Server", ".\\Sqldeveloper");
}
set
{
Write("Server", value);
}
}
public string Database
{
get
{
return Read("Database", "Shop2");
}
set
{
Write("Database", value);
}
}
private static string Read(string name, string #default)
{
RegistryKey key = Registry.CurrentUser.OpenSubKey(Path, false);
if (key == null)
return #default;
try
{
string result = key.GetValue(name).ToString();
key.Close();
return result;
}
catch
{
return #default;
}
}
private static void Write(string name, string value)
{
try
{
RegistryKey key = Registry.CurrentUser.OpenSubKey(Path, true);
if (key == null)
key = Registry.CurrentUser.CreateSubKey(Path);
key.SetValue(name, value);
key.Close();
}
catch
{
}
}
}
}

If you're asking if you can eliminate the private field for your Current property, you could do this (though it would no longer initialise Configuration lazily):
public class Configuration
{
static Configuration()
{
Current = new Configuration();
}
public static Configuration Current { get; private set; }
}
Note: This is an Auto-Implemented Property and requires C# 3.0.
You could also use a public field instead (though if you ever need to change this to a property, you would need to recompile anything that's calling it):
public class Configuration
{
public static Configuration Current = new Configuration();
}

Related

Neo4jClient Node/Relationship Class conventions

Is there a standard naming convention for the properties/methods of a node/relationship class when working with Neo4jClient?
I'm following this link Neo4jClient - Retrieving relationship from Cypher query to create my relationship class
However, there are certain properties of my relationship which i can't get any value despite the relationship having it. While debugging my code, i realized certain properties was not retrieved from the relationship when creating the relationship object.
this is my relationship class
public class Creates
{
private string _raw;
private int _sourcePort;
private string _image;
private int _DestinationPort;
private int _eventcode;
private string _name;
private string _src_ip;
private int _src_port;
private string _dvc;
private int _signature_ID;
private string _dest_ip;
private string _computer;
private string _sourceType;
private int _recordID;
private int _processID;
private DateTime _time;
private int _dest_port;
public string Raw { get { return _raw; } set { _raw = value; } }
public int SourcePort { get { return _sourcePort; } set { _sourcePort = value; } }
public string Image { get { return _image; } set { _image = value; } }
public int DestinationPort { get { return _DestinationPort; } set { _DestinationPort = value; } }
public int Eventcode { get { return _eventcode; } set { _eventcode = value; } }
public string Name { get { return _name; } set { _name = value; } }
public string Src_ip { get { return _src_ip; } set { _src_ip = value; } }
public int Src_port { get { return _src_port; } set { _src_port = value; } }
public string DVC { get { return _dvc; } set { _dvc = value; } }
public int Signature_ID { get { return _signature_ID; } set { _signature_ID = value; } }
public string Dest_ip { get { return _dest_ip; } set { _dest_ip = value; } }
public string Computer { get { return _computer; } set { _computer = value; } }
public string SourceType { get { return _sourceType; } set { _sourceType = value; } }
public int RecordID { get { return _recordID; } set { _recordID = value; } }
public int ProcessID { get { return _processID; } set { _processID = value; } }
public DateTime Indextime { get { return _time; } set { _time = value; } }
public int Dest_port { get { return _dest_port; } set { _dest_port = value; } }
}
This is another class
public class ProcessConnectedIP
{
public Neo4jClient.RelationshipInstance<Pivot> bindto { get; set; }
public Neo4jClient.Node<LogEvent> bindip { get; set; }
public Neo4jClient.RelationshipInstance<Pivot> connectto { get; set; }
public Neo4jClient.Node<LogEvent> connectip { get; set; }
}
This is my neo4jclient query to get the relationship object
public IEnumerable<ProcessConnectedIP> GetConnectedIPs(string nodeName)
{
try
{
var result =
this.client.Cypher.Match("(sourceNode:Process{name:{nameParam}})-[b:Bind_IP]->(bind:IP_Address)-[c:Connect_IP]->(connect:IP_Address)")
.WithParam("nameParam", nodeName)
.Where("b.dest_ip = c.dest_ip")
.AndWhere("c.Image=~{imageParam}")
.WithParam("imageParam", $".*" + nodeName + ".*")
.Return((b, bind, c, connect) => new ProcessConnectedIP
{
bindto = b.As<RelationshipInstance<Creates>>(),
bindip = bind.As<Node<LogEvent>>(),
connectto = c.As<RelationshipInstance<Creates>>(),
connectip = connect.As<Node<LogEvent>>()
})
.Results;
return result;
}catch(Exception ex)
{
Console.WriteLine("GetConnectedIPs: Error Msg: " + ex.Message);
return null;
}
}
This is the method to read the results
public void MyMethod(string name)
{
IEnumerable<ProcessConnectedIP> result = clientDAL.GetConnectedIPs(name);
if(result != null)
{
var results = result.ToList();
Console.WriteLine(results.Count());
foreach (ProcessConnectedIP item in results)
{
Console.WriteLine(item.Data.Src_ip);
Console.WriteLine(item.bindto.StartNodeReference.Id);
Console.WriteLine(item.bindto.EndNodeReference.Id);
Console.WriteLine(item.connectto.StartNodeReference.Id);
Console.WriteLine(item.connectto.EndNodeReference.Id);
Node<LogEvent> ans = item.bindip;
LogEvent log = ans.Data;
Console.WriteLine(log.Name);
Node<LogEvent> ans1 = item.connectip;
LogEvent log1 = ans1.Data;
Console.WriteLine(log1.Name);
}
}
}
Somehow, i'm only able to populate the relationship object with src_ip/src_port/dest_ip/dest_port values. the rest are empty.
Is there any possible reason why? I've played with upper/lower cases on the properties names but it does not seem to work.
This is the section of the graph im working with
This is the relationship properties sample:
_raw: Some XML dataSourcePort: 49767Image: C:\Windows\explorer.exeDestinationPort: 443EventCode: 3Name: Bind
IPsrc_ip: 172.10.10.104dvc: COMPUTER-NAMEsrc_port:
49767signature_id: 3dest_ip: 172.10.10.11Computer:
COMPUTRE-NAME_sourcetype:
XmlWinEventLog:Microsoft-Windows-Sysmon/OperationalRecordID:
13405621ProcessId: 7184_time: 2017-08-28T15:15:39+08:00dest_port: 443
I'm not entirely sure how your Creates class is ever populated, in particular those fields - as your Src_port property doesn't match the src_port in the sample you provided (case wise).
I think it's probably best to go back to a super simple version. Neo4jClient will map your properties to the properties in the Relationship as long as they have the same name (and it is case-sensitive).
So start with a new Creates class (and use auto properties - it'll make your life a lot easier!)
public class Creates
{
public string Computer { get; set; }
}
Run your query with that and see if you get a result, then keep on adding properties that match the name and type you expect to get back (int, string etc)
It seems that i have to give neo4j node/relationship property names in lowercase and without special characters at the start of the property name, in order for the above codes to work.
The graph was not created by me at the start thus i had to work on it with what was given. I had to get the developer who created the graph to create the nodes with lowercases in order for the above to work.

Getting new items added to an Observable Collection of a custom class

I have a set of classes that I am using to deserialize JSON into. My program will periodically look for changes to this JSON file, and if it finds any, will push the new data to the properties of these classes using reflection.
I need to find any new items added to the collection of the Item2 class (SocialExportJSON.SocialExportData.Item2) after a successful update.
My JSON classes look like this (there are more but I want to avoid too big a wall of code):
public class Item2 : INotifyPropertyChanged
{
[JsonProperty("type")]
private string type;
public string Type
{
get
{
return type;
}
set
{
if (type != value)
{
type = value;
RaisePropertyChanged("Type");
}
}
}
[JsonProperty("id")]
private string id;
public string ID
{
get
{
return id;
}
set
{
if (id != value)
{
id = value;
RaisePropertyChanged("ID");
}
}
}
[JsonProperty("postedIso8601")]
private string postedIso8601;
public string PostedIso8601
{
get
{
return postedIso8601;
}
set
{
if (postedIso8601 != value)
{
postedIso8601 = value;
RaisePropertyChanged("PostedIso8601");
}
}
}
[JsonProperty("postedTimestamp")]
private object postedTimestamp;
public object PostedTimestamp
{
get
{
return postedTimestamp;
}
set
{
if (postedTimestamp != value)
{
postedTimestamp = value;
RaisePropertyChanged("PostedTimestamp");
}
}
}
[JsonProperty("engagement")]
private Engagement engagement;
public Engagement Engagement
{
get
{
return engagement;
}
set
{
if (engagement != value)
{
engagement = value;
RaisePropertyChanged("Engagement");
}
}
}
[JsonProperty("source")]
private Source2 source;
public Source2 Source
{
get
{
return source;
}
set
{
if (source != value)
{
source = value;
RaisePropertyChanged("Source");
}
}
}
[JsonProperty("author")]
private Author author;
public Author Author
{
get
{
return author;
}
set
{
if (author != value)
{
author = value;
RaisePropertyChanged("Author");
}
}
}
[JsonProperty("content")]
private Content content;
public Content Content
{
get
{
return content;
}
set
{
if (content != value)
{
content = value;
RaisePropertyChanged("Content");
}
}
}
[JsonProperty("location")]
private Location location;
public Location Location
{
get
{
return location;
}
set
{
if (location != value)
{
location = value;
RaisePropertyChanged("Location");
}
}
}
[JsonProperty("publication")]
private Publication publication;
public Publication Publication
{
get
{
return publication;
}
set
{
if (publication != value)
{
publication = value;
RaisePropertyChanged("Publication");
}
}
}
[JsonProperty("metadata")]
private Metadata metadata;
public Metadata Metadata
{
get
{
return metadata;
}
set
{
if (metadata != value)
{
metadata = value;
RaisePropertyChanged("Metadata");
}
}
}
//Event handling
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged(string property)
{
//Console.WriteLine("Updated");
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property));
}
}
public class SocialExportData : INotifyPropertyChanged
{
[JsonProperty("dataType")]
private string dataType;
public string DataType
{
get
{
return dataType;
}
set
{
if (dataType != value)
{
dataType = value;
RaisePropertyChanged("DataType");
}
}
}
[JsonProperty("id")]
private int id;
public int ID
{
get
{
return id;
}
set
{
if (id != value)
{
id = value;
RaisePropertyChanged("ID");
}
}
}
[JsonProperty("story")]
private Story story;
public Story Story
{
get
{
return story;
}
set
{
if (story != value)
{
story = value;
RaisePropertyChanged("Story");
}
}
}
[JsonProperty("order")]
private string order;
public string Order
{
get
{
return order;
}
set
{
if (order != value)
{
order = value;
RaisePropertyChanged("Order");
}
}
}
[JsonProperty("lifetime")]
private string lifetime;
public string Lifetime
{
get
{
return lifetime;
}
set
{
if (lifetime != value)
{
lifetime = value;
RaisePropertyChanged("Lifetime");
}
}
}
[JsonProperty("maxAge")]
private int maxAge;
public int MaxAge
{
get
{
return maxAge;
}
set
{
if (maxAge != value)
{
maxAge = value;
RaisePropertyChanged("MaxAge");
}
}
}
[JsonProperty("maxSize")]
private int maxSize;
public int MaxSize
{
get
{
return maxSize;
}
set
{
if (maxSize != value)
{
maxSize = value;
RaisePropertyChanged("MaxSize");
}
}
}
[JsonProperty("consumeCount")]
private int consumeCount;
public int ConsumeCount
{
get
{
return consumeCount;
}
set
{
if (consumeCount != value)
{
consumeCount = value;
RaisePropertyChanged("ConsumeCount");
}
}
}
[JsonProperty("consumeInterval")]
private int consumeInterval;
public int ConsumeInterval
{
get
{
return consumeInterval;
}
set
{
if (consumeInterval != value)
{
consumeInterval = value;
RaisePropertyChanged("ConsumeInterval");
}
}
}
[JsonProperty("items")]
private ObservableCollection<Item2> items;
public ObservableCollection<Item2> Items
{
get
{
return items;
}
set
{
if (items != value)
{
items = value;
RaisePropertyChanged("Items");
}
}
}
//Event handling
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged(string property)
{
//Console.WriteLine("Updated");
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property));
}
}
public class SocialExportJSON : INotifyPropertyChanged
{
[JsonProperty("id")]
private string id;
public string ID
{
get
{
return id;
}
set
{
if (id != value)
{
id = value;
RaisePropertyChanged("ID");
}
}
}
[JsonProperty("ttl")]
private int ttl;
public int TTL
{
get
{
return ttl;
}
set
{
if (ttl != value)
{
ttl = value;
RaisePropertyChanged("TTL");
}
}
}
[JsonProperty("serial")]
private long serial;
public long Serial
{
get
{
return serial;
}
set
{
if (serial != value)
{
serial = value;
RaisePropertyChanged("Serial");
}
}
}
[JsonProperty("formatType")]
private string formatType;
public string FormatType
{
get
{
return formatType;
}
set
{
if (formatType != value)
{
formatType = value;
RaisePropertyChanged("FormatType");
}
}
}
[JsonProperty("modifiedIso8601")]
private string modifiedIso8601;
public string ModifiedIso8601
{
get
{
return modifiedIso8601;
}
set
{
if (modifiedIso8601 != value)
{
modifiedIso8601 = value;
RaisePropertyChanged("ModifiedIso8601");
}
}
}
[JsonProperty("modifiedTimestamp")]
private long modifiedTimestamp;
public long ModifiedTimestamp
{
get
{
return modifiedTimestamp;
}
set
{
if (modifiedTimestamp != value)
{
modifiedTimestamp = value;
RaisePropertyChanged("ModifiedTimestamp");
}
}
}
[JsonProperty("timezone")]
private string timezone;
public string Timezone
{
get
{
return timezone;
}
set
{
if (timezone != value)
{
timezone = value;
RaisePropertyChanged("Timezone");
}
}
}
[JsonProperty("dataType")]
private string dataType;
public string DataType
{
get
{
return dataType;
}
set
{
if (dataType != value)
{
dataType = value;
RaisePropertyChanged("DataType");
}
}
}
[JsonProperty("exports")]
private ObservableCollection<SocialExportData> exports;
public ObservableCollection<SocialExportData> Exports
{
get
{
return exports;
}
set
{
if (exports != value)
{
exports = value;
RaisePropertyChanged("Exports");
}
}
}
//Event handling
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged(string property)
{
//Console.WriteLine("Updated");
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property));
}
}
In another class, I have a method to deserialize to a global instance of my JSON class. It looks like this:
public SocialExportJSON socialExportData;
private async void DownloadAndDeserializeJSONAsync()
{
try
{
//Create a web client with the supplied credentials
var exportClient = new WebClient { Credentials = new NetworkCredential(uName, pw), Encoding = Encoding.UTF8};
//Create a task to download the JSON string and wait for it to finish
var downloadTask = Task.Run(() => exportClient.DownloadString(new Uri(eURL)));
downloadTask.Wait();
//Get the string from the task
var JSONString = await downloadTask;
//Create a task to deserialize the JSON from the last task
var DeserializeTask = Task.Run(() => JsonConvert.DeserializeObject<SocialExportJSON>(JSONString));
DeserializeTask.Wait();
SocialExportJSON sej = await DeserializeTask;
//Check the timestamp first to see if we should change the data
if(socialExportData == null)
{
//Get the data from the task
socialExportData = await DeserializeTask;
}
else if(sej.ModifiedTimestamp != socialExportData.ModifiedTimestamp)
{
//Get the data from the task
SocialExportJSON newData = await DeserializeTask;
GetNewItems(newData);
SetNewData(newData);
//Call the exportUpdated event when the task has finished
exportUpdated();
}
}
catch (Exception e)
{
MessageBox.Show(e.Message.ToString());
}
}
In my SetNewData function, shown below, I use reflection to set the properties of my global class. Because I'm setting the whole collection rather than iterating through each of the properties in each of the classes, I can't use the CollectionChanged event to find new items.
public void SetNewData(SocialExportJSON newData)
{
//Loop through each of the properties and copy from source to target
foreach (PropertyInfo pi in socialExportData.GetType().GetProperties())
{
if (pi.CanWrite)
{
pi.SetValue(socialExportData, pi.GetValue(newData, null), null);
}
}
}
Is there a way I can modify my SetNewData function in such a way that it calls CollectionChanged? If not, what would be the best way to go about getting any new additions to my collection of Item2?
In my Main function. I create an instance of my class called SocialExport like so:
SocialExport s = new SocialExport("http://example.json", "example", "example");.
This class is where the global instance of my JSON class is contained, and my event handler is added like so
s.socialExportData.Exports[0].Items.CollectionChanged += CollectionChanged;
Then you are hooking up an event handler for the CollectionChanged event for that particular instance of ObservableCollection<Item2>.
If you create a new ObservableCollection<Item2>, you obviously must hook up an event handler to this one as well. The event handler that is associated with the old object won't be invoked when new items are added to the new instance.
So whenever a new ObservableCollection<Item2> is created, using deserialization or not, you should hook up a new event handler.
You could probably do this in your DownloadAndDeserializeJSONAsync method. The other option would be to create only one instance of the collection and remove and add items from/to this one.

Enterprise Library Mappings

Is there a way to map database fields to OOP complex type fields with Enterprise Library. I am calling stored procedures that retrieves all data that I would like to store into custom class.
Here I retrieve data from sp:
IEnumerable<WorkHistoryGrid> data = new List<WorkHistoryGrid>();
return db.ExecuteSprocAccessor<WorkHistoryGrid>("PensionPDF_RetrieveParticipantWorkHistoryForFund", pensionId, fund);
And here is my class
public class WorkHistoryGrid : BindableBase
{
private string _rateType;
private string _fundType;
private string _employer;
private string _employerName;
private string _local;
private string _dateBalanced;
private string _plan;
private string _fund;
private WorkHistoryGridMergeData _mergeData;
#region Properties
public WorkHistoryGridMergeData MergeData
{
get { return _mergeData; }
set { SetProperty(ref _mergeData, value); }
}
public string RateType
{
get { return _rateType; }
set { SetProperty(ref _rateType, value); }
}
public string FundType
{
get { return _fundType; }
set { SetProperty(ref _fundType, value); }
}
public string Employer
{
get { return _employer; }
set { SetProperty(ref _employer, value); }
}
public string EmployerName
{
get { return _employerName; }
set { SetProperty(ref _employerName, value); }
}
public string Local
{
get { return _local; }
set { SetProperty(ref _local, value); }
}
public string DateBalanced
{
get { return _dateBalanced; }
set { SetProperty(ref _dateBalanced, value); }
}
public string Plan
{
get { return _plan; }
set { SetProperty(ref _plan, value); }
}
public string Fund
{
get { return _fund; }
set { SetProperty(ref _fund, value); }
}
}
}
}
It works fine if I would create one class with all database fields, but I would like to have more control over it by mapping database fields to custom complex type properties.
Here is the answer in my case, in case someone would look for similar solution:
var workHistoryGridSetMapper = new WorkHistoryGridSetMapper();
db.ExecuteSprocAccessor<WorkHistoryGrid>("PensionPDF_RetrieveParticipantWorkHistory", workHistoryGridSetMapper, pensionId);
IResultSetMapper
public class WorkHistoryGridSetMapper : IResultSetMapper<WorkHistoryGrid>
{
public IEnumerable<WorkHistoryGrid> MapSet(IDataReader reader)
{
List<WorkHistoryGrid> workHistoryLst = new List<WorkHistoryGrid>();
using (reader) // Dispose the reader when we're done
{
while (reader.Read())
{
WorkHistoryGrid workHist = new WorkHistoryGrid();
workHist.Amount = reader.GetValue(reader.GetOrdinal("Amount")).ToString();
workHist.DateBalanced = reader.GetValue(reader.GetOrdinal("DateBalanced")).ToString();
workHist.Employer = reader.GetValue(reader.GetOrdinal("Employer")).ToString();
workHist.EmployerName = reader.GetValue(reader.GetOrdinal("EmployerName")).ToString();
workHist.Fund = reader.GetValue(reader.GetOrdinal("Fund")).ToString();
workHist.FundType = reader.GetValue(reader.GetOrdinal("FundType")).ToString();
workHist.Hours = reader.GetValue(reader.GetOrdinal("Hours")).ToString();
workHist.Local = reader.GetValue(reader.GetOrdinal("Local")).ToString();
workHist.Period = reader.GetValue(reader.GetOrdinal("Period")).ToString();
workHist.Plan = reader.GetValue(reader.GetOrdinal("Plan")).ToString();
workHist.RateAmount = reader.GetValue(reader.GetOrdinal("RateAmount")).ToString();
workHist.RateType = reader.GetValue(reader.GetOrdinal("RateType")).ToString();
workHist.Status = reader.GetValue(reader.GetOrdinal("Status")).ToString();
workHist.WorkMonth = reader.GetValue(reader.GetOrdinal("WorkMonth")).ToString();
workHist.MergeData = new WorkHistoryGridMergeData
{
MergeDateMerged = reader.GetValue(reader.GetOrdinal("MergeDateMerged")).ToString(),
MergeLastUpdated = reader.GetValue(reader.GetOrdinal("MergeLastUpdated")).ToString(),
MergeLastUpdatedUserId = reader.GetValue(reader.GetOrdinal("MergeLastUpdatedUserId")).ToString(),
MergeLastUpdatedUserType = reader.GetValue(reader.GetOrdinal("MergeLastUpdatedUserType")).ToString(),
MergeNewSsn = reader.GetValue(reader.GetOrdinal("MergeNewSsn")).ToString(),
MergeNotes = reader.GetValue(reader.GetOrdinal("MergeNotes")).ToString(),
MergeOldSsn = reader.GetValue(reader.GetOrdinal("MergeOldSsn")).ToString(),
MergeTrustId = reader.GetValue(reader.GetOrdinal("MergeTrustId")).ToString(),
MergeUserName = reader.GetValue(reader.GetOrdinal("MergeUserName")).ToString()
};
workHistoryLst.Add(workHist);
};
}
return workHistoryLst;
}
}

Unable to store data to a local XML file

I have the following code which I'm trying to use to save and load data from a settings XML file on my phone (the caller is accessed via an interface in a PCL)
// caller
public void SetStringValue(string name, string val)
{
UserData.SetPropertyValue(this, name, val);
}
// userdata file
namespace PreferencesXML.iOS
{
public static class UserData
{
public static object GetPropertyValue(object data, string propertyName)
{
return data.GetType().GetProperties().SingleOrDefault(pi => pi.Name == propertyName).GetValue(data, null);
}
public static void SetPropertyValue<T>(object data, string propertyName, T value)
{
data.GetType().GetProperties().SingleOrDefault(pi => pi.Name == propertyName).SetValue(data, value);
}
private static string pUserSettingsFile;
private static UserSetting userSetting;
public static UserSetting UserSetting
{
get
{
if (userSetting == null)
{
if (File.Exists(UserSettingsFile))
{
userSetting = Serialiser.XmlDeserializeObject<UserSetting>(UserSettingsFile);
}
else
{
userSetting = new UserSetting();
Serialiser.XmlSerializeObject(userSetting, UserSettingsFile);
}
}
return userSetting;
}
set
{
if (value == null)
{
throw new ArgumentNullException("value is null!");
}
// end if
userSetting = value;
if (File.Exists(UserSettingsFile))
{
File.Delete(UserSettingsFile);
}
Serialiser.XmlSerializeObject(userSetting, UserSettingsFile);
}
}
public static string UserSettingsFile
{
get
{
if (string.IsNullOrEmpty(pUserSettingsFile))
{
pUserSettingsFile = Path.Combine(AppDelegate.Self.ContentDirectory, "UserSettings.xml");
}
return pUserSettingsFile;
}
}
public static string Company
{
get
{
return UserSetting.companyName;
}
set
{
UserSetting settings = UserSetting;
settings.companyName = value;
UserSetting = settings;
}
}
public static double Pi
{
get
{
return UserSetting.pi;
}
set
{
UserSetting settings = UserSetting;
settings.pi = value;
UserSetting = settings;
}
}
public static bool OnOff
{
get
{
return UserSetting.onOff;
}
set
{
UserSetting settings = UserSetting;
settings.onOff = value;
UserSetting = settings;
}
}
}
public class UserSetting
{
public string companyName{ get; set; }
public double pi{ get; set; }
public bool onOff{ get; set; }
}
}
As you can see, it's not doing anything mind boggling difficult. The reader part of this works fine, but the SetPropertyValue constantly returns a fail at the SingleOrDefault.
This is down to the caller extension method extending the class the caller is in rather than the UserData class.
As the UserData class is static, I can't create an object instance of it and pass that in in place of the this parameter, neither can I pass UserData in directly or as a generic parameter (such as this.SetPropertyValue<UserData>(...)). I've attempted to make the class non-static, which gets me a bit further, but not much.
Is there a way that I can use this code to store data to and from my UserData class?

ConfigurationProperty(typeof(CCfgElement).ToString())

Why is it not possible to have this ?
[ConfigurationProperty(typeof(CCfgElement).ToString())]
I get the error:
Error 1 An attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter type
here is my code
public class CConfigElement<T> : ConfigurationElement
{
}
public class CConfigSection<CCfgElement> : ConfigurationSection where CCfgElement : CConfigElement<CCfgElement>
{
// Create a element.
[ConfigurationProperty(typeof(CCfgElement).ToString())]
public CCfgElement Element
{
get { return (CCfgElement)this[typeof(CCfgElement).ToString()]; }
set { this[typeof(CCfgElement).ToString()] = value; }
}
}
I do not think there is any workarounds but
can anybody tell me how to add a section lement with code?
Søren
I found a kind of solution my self
here is my code
// create the DataModel in your MainWindow or App
// CTestDataModel t = new CTestDataModel();
public class CTestDataModel
{
CTestValues _Cfg;
// Create values to save in cofig
public class CTestValues : ConfigurationElement
{
[ConfigurationProperty("Param", DefaultValue = 11, IsRequired = true)]
public int Param
{
get { return (int)this["Param"]; }
set { this["Param"] = value; }
}
[ConfigurationProperty("Param1", DefaultValue = "22", IsRequired = true)]
public double Param1
{
get { return (double)this["Param1"]; }
set { this["Param1"] = value; }
}
[ConfigurationProperty("Time", IsRequired = true)]
public DateTime Time
{
get { return (DateTime)this["Time"]; }
set { this["Time"] = value; }
}
}
public CTestDataModel()
{
// load config
_Cfg = CConfiguration.Element<CTestValues>();
// Use values
int t = _Cfg.Param;
_Cfg.Param = 5;
_Cfg.Param1 = 6;
_Cfg.Time = new DateTime(1962, 10, 10);
}
}
public class CConfigSection<CCfgElement> : ConfigurationSection where CCfgElement : ConfigurationElement
{
// Create a element.
[ConfigurationProperty("Element")]
public CCfgElement Element
{
get { return (CCfgElement)this["Element"]; }
set { this["Element"] = value; }
}
}
public static class CConfiguration
{
static Configuration config = null;
static AppSettingsSection appSettings = null;
static CConfiguration()
{
config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
appSettings = config.AppSettings;
AppDomain.CurrentDomain.ProcessExit += CConfiguration_Dtor;
}
private static void CConfiguration_Dtor(object sender, EventArgs e)
{
config.Save(ConfigurationSaveMode.Modified, true);
}
// Uses sections
private static String MakeSectionName(String name)
{
return name.Replace('+', '.');
}
public static void RemoveSection(Type T)
{
try
{
String name = MakeSectionName(T.ToString());
config.Sections.Remove(name);
}
catch (Exception)
{
return;
}
}
public static T Element<T>() where T : ConfigurationElement
{
try
{
return Section<T>().Element;
}
catch (Exception ex)
{
Debug.WriteLine(typeof(T).ToString()+" error: "+ex.Message);
throw ex;
}
}
public static CConfigSection<T> Section<T>() where T : ConfigurationElement
{
try
{
return Section(typeof(T).ToString(), new CConfigSection<T>()) as CConfigSection<T>;
}
catch (Exception ex)
{
Debug.WriteLine(typeof(T).ToString()+" error: "+ex.Message);
throw ex;
}
}
public static ConfigurationSection Section(String name, ConfigurationSection section)
{
try
{
name = MakeSectionName(name);
ConfigurationSection cs = config.Sections.Get(name);
if (cs == null)
{
config.Sections.Add(name, section);
return section;
}
else
return cs;
}
catch (Exception)
{
config.Sections.Remove(name);
config.Sections.Add(name, section);
return section;
}
}
// Uses AppSettings
public static bool Exist(String key)
{
return appSettings.Settings[key] != null;
}
public static string Read(String key, string Default = "")
{
if (Exist(key))
return appSettings.Settings[key].Value;
return Default;
}
public static void Write(string key, string value)
{
if (Exist(key))
appSettings.Settings.Remove(key);
appSettings.Settings.Add(key, value);
}
public static void Remove(string key)
{
if (Exist(key))
appSettings.Settings.Remove(key);
}
public static new string ToString()
{
StringBuilder sb = new StringBuilder();
// Get the settings collection (key/value pairs).
if (appSettings.Settings.Count != 0)
{
foreach (string key in appSettings.Settings.AllKeys)
{
string value = appSettings.Settings[key].Value;
sb.Append(String.Format("Key: {0} Value: {1}\r\n", key, value));
}
}
return sb.ToString();
}
}

Categories

Resources