I have a simple question (I think) that I'm not making much progress finding an answer to with Google. I have a structure as follows:
/// <summary>
/// A class to represent the sync settings for a single camera.
/// </summary>
public class CameraSyncSettings
{
public string ID { get; set; }
public string SyncPath { get; set; }
public bool OverwriteExisting { get; set; }
};
And then an array of these in the program, one for each camera:
List<CameraSyncSettings> MyCameraSettings = new List<CameraSyncSettings>();
Now, what I want to do is have a property in my settings such that I can read/write this array into it to persist the information between sessions.
How can I do this and what is the best/most efficient way?
You can achieve it by using Properties.Settings of type ListDictionary
Example:
Properties.Settings.Default.Example.Add("Setting1", new CameraSyncSettings());
Properties.Settings.Default.Example.Add("Setting2", new CameraSyncSettings());
Properties.Settings.Default.Example.Add("Setting3", new CameraSyncSettings());
Properties.Settings.Default.Save();
see link for more information : http://msdn.microsoft.com/en-us/library/aa730869(v=vs.80).aspx
NB: You can set the Scope of Properties.Settings.Default.Example to Application or User
As we've cleared in the comments you want to use app.config: this project should pretty much cover all your needs.
Related
Suppose the following baseline design: I have a class CarElement which holds properties and methods related to both visual representation and data model/logic representation of a car:
class carElement
{
// UI related properties and methods:
public Size DrawSize { get; set; }
public Point Location { get; set; }
public void Draw()
{
// do something...
}
// data model / logic related properties and methods:
public double weight { get; set; }
public string manufacturer { get; set; }
public double CalculatePrice()
{
// do something...
return 0;
}
}
The usage of this class is as follows: Multiple instances of carElement are drawn to some canvas. Clicking each drawn car shows the properties of that car in a property grid by using propertygrid.SelectedObject = InstanceOfcarElement.
In my opinion, this design is flawed because data model and visual representation are not separated in the class design. I would like to improve the design towards MVC and I am seeking advice on good design decisions.
My current take on this would be to separate above class carElement into something like the following two classes.
class carUIElement // organizes visual representation of a car
{
public Size DrawSize { get; set; }
public Point Location { get; set; }
private carDataElement linkedCarDataElement;
public void Draw()
{
// do something...
}
}
class carDataElement // organizes data model organization of a car
{
public double weight { get; set; }
public string manufacturer { get; set; }
private carUIElement linkedCarUIElement;
public double CalculatePrice()
{
// do something...
return 0;
}
}
With that approach, the following are unclear to me:
carUIElement should know the carDataElement it is linked to, and vice versa. Are there better design approaches to this than the simple linking in above Code?
How would I best show both the UI and data model properties on the property Grid, when the drawn UIElement is clicked?
Is the overall approach viable? What about the above open points? I am missing the experience to judge that, so I would be grateful for your comments. Thank you.
Well while we should always be careful not to over intellectualize stuff, after all we as programmers are more masons than artist and even if Notre Dame church is just a construction and not art, no always will be required exorbitant decoration and acoustic chambers, suppose the next version will be as grand as the previous :)
What do i mean? I propose pragmatism with MVC, so if and if in early infancy of the program, it can have the ui model, also sometimes called the data transfer object, be identical to the logical model, that is not in itself an anti-pattern imo.
Obviously once bulding ui, we begin to have released instances with presumed constructs and when it starts to limit development of the product, how it is presented, typically when you need more info than is relevant to ui, stored on the entity, then you can lock the interface by inventing the DTO model objects and party on with the initial model.
So I get where you're going with what's behind why you might want to separate it.
Then again often we have web frontends, especially with mvc and then mostly it will be no longer a databound view, but a MVVM thingy like like Angular, React, Vue or even Blazor if for some reason you might want that, or the tradition Razor pages, really? in new development??
I try not to put anything in the DTO classes that would be lost if only the serialized JSON version is available to your view engine. So that when modernization happens, your controller/ api doesn't have to principally change.
So seperate classes for seperate concerns an no logic in data access or transfer classes, my suggestion would be something along the lines below, but to end up with your questions:
a) Linking with a navigation property in your data model makes sense if you use it to load for instance using entity framework, it is required.
In Your UI type the frequency is key, typically we like to push all data into the points so that they need nothing else to perform, but this makes sense if the class is being serialized and deserialized and you use a tool like AutoMapper to move to and from, if You're in a windows client like WPF hey your model is already on the client and already loaded up for MVVM, you're in such a much better place that you may not honestly care for front-end types, until they need to vary.
b) the question is do you always want to show both or can you hide the cardata element until they ask for it, that would dictate the choice to either let a DTO include the data from the relation or just the foreign key and have an extra lookup method available imo.
So suggestion brief:
/// <summary>
/// Drawing is a separate concern of the application
/// </summary>
class DrawManager
{
public void DrawCar(CarBase car) { }
}
/// <summary>
/// So is calculating prices
/// </summary>
class PriceManager
{
decimal CalculateCarPrice(CarBase car) { throw new NotImplementedException(); }
}
/// <summary>
/// The 2 classes share properties, invent a base class to abide by the DRY principle
/// </summary>
class CarBase
{
public Size DrawSize { get; set; }
public Point Location { get; set; }
}
/// <summary>
/// Now they are identical
/// </summary>
class carElement : CarBase
{
carDataElement CarData { get; set; }
}
/// <summary>
/// Now they are identical
/// </summary>
class carUIElement : CarBase
{
carDataElement linkedCarDataElement;
}
/// <summary>
/// The data about a car, in RDBMS typically normalized into a seperate entity like you have,
/// does UI really need any of them? Is it always needed when other members are accessed?
/// </summary>
/// <remarks>
/// we could choose to have the data model have a navigation property and then let the ui member not have it and give it a method to ackquire it,
/// but then that shouldn't get done to early and well if it always needs it, it is not yet a seperate datatype justification for the ui aspect
/// </remarks>
class carDataElement
{
public double weight { get; set; }
public string manufacturer { get; set; }
}
I'm using Swagger.AspNetCore to document my api. So far i was happy to use xml comments to generate response model examples until i reach the point when i've got to document embeded object. So i have simple model:
public class SummaryResult
{
/// <summary>Total Cost.</summary>
/// <value>Total Cost.</value>
/// <example>6433.2</example>
public double TotalCost { get; set; }
/// <summary>Owner.</summary>
public Owner Owner { get; set; }
}
public class Owner
{
/// <summary>Owner Name.</summary>
/// <value>Owner Name.</value>
/// <example>Michael</example>
public string Name { get; set; }
}
And Swagger UI document it only for TotalCost, Owner property just skipped whatever i do. Does anyone have a clue why this can happen? And how to fix it.
I know how to deal with List - just put on top xml comment like <list></list> but it's not my case.
Thank you
I just tested this and it shows fine on my end:
http://swagger-net-test.azurewebsites.net/swagger/ui/index#/ActionFilter/ActionFilter_Get
Here is how that looks like on the model tab:
As you can see in the image it does show the summary and the example value.
Here is the code:
https://github.com/heldersepu/Swagger-Net-Test/blob/master/Swagger_Test/Controllers/ActionFilterController.cs#L29
Educated guess there could be something else removing those elements.
I'm sorry if it's confusing, but I don't really know how to word my question.
My C# class is filled with data from API JSON response, it looks as follows:
[DataContract(Name = "user")]
public class User
{
[DataMember(Name="id")]
public int Id { get; set; }
[DataMember(Name="email")]
public string Email { get; set; }
[DataMember(Name="name")]
public string Name { get; set; }
}
I would like to do things like finding an user from User object list, based on some data I have.
There are tutorials made by Microsoft about working with classes, they imply that I know what's inside by storing just added element in a variable.
My issue is that I need to find the User (specifically id) using email - I don't know how to start on this one.
The other MS doc shows that I can just iterate through all elements of User, and then I suppose I could find the id with a simple if statement?... No way it's optimal, considering there are over thousand entries.
Could somebody advise if XML Serialization is achievable with my design?
I have written the code for the core functionality for my 'System Administration' application. For Sprint 1 of my project, I have to store all data in a temporary XML data store which will be replaced using ADO.Net in Sprint 2.
I have looked into serializing classes using XML Serialization such as in below articles:
https://www.codeproject.com/Articles/483055/XML-Serialization-and-Deserialization-Part
https://www.codeproject.com/Articles/487571/XML-Serialization-and-Deserialization-Part-2
I have the following classes which (I think) need to be stored as XML:
A User class with multiple properties
A UserAccessGroup class with a String property Name and a List of ints UserIDs
A UserAdministration Class that holds a List of all User objects and one or more UserAccessGroup objects (constructor uses params UserAccessGroup[]). It has methods for adding/deleting users on the system, adding/deleting UserIDs from a UserAccessGroup.
A UserVerification Class that holds a UserAdministration object and the UserAccessGroup object for the application being logged on to. It also has two ints for counting failed and successful logon attempts a method for logging on which returns true if all conditions are met, otherwise false.
A ServiceRequest class with multiple properties
A ServiceRequestTracker class that holds a list of all ServiceRequest objects and has methods for adding/deleting/editing them.
I have the below code in my Program file:
static void Main()
{
UserAccessGroup SystemAdmin_App = new UserAccessGroup("Admin Operators");
UserAccessGroup Shareholder_App = new UserAccessGroup("Shareholders");
UserAccessGroup Broker_App = new UserAccessGroup("Brokers");
UserAccessGroup StockExMgr_App = new UserAccessGroup("StockExMgrs");
UserIDGenerator IDGenerator = new UserIDGenerator();
UserAdministration userAdmin = new UserAdministration(IDGenerator,
SystemAdmin_App, Shareholder_App, Broker_App, StockExMgr_App);
UserVerificationService userVerification = new UserVerificationService(
userAdmin, SystemAdmin_App);
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
LoginScreen myLoginScreen = new LoginScreen();
Application.Run(myLoginScreen);
}
Only now that I have finished writing all of my classes using TDD have I looked into storing object data as XML. I am finding it very confusing to apply XML Serialization to my design and I am wondering if it is possible to achieve this without completely re-designing my application from scratch?
Any help here would be greatly appreciated!
As per the discussion in comments, I'll give you a basic overview of how you can quickly (de)serialize custom classes.
For reference, here's your comment to which I'm replying:
#Flater Thanks for the reply! I'm still unsure how to do serialize my objects. For example, UserAdministration contains a list of Users and has methods for adding/removing Users from the list. Say for example, I add a new user by calling the addUser method of UserAdministration. How does the new User object get added to the XML file?
I always use this helper class because it makes the code so much cleaner. I've copied it from the internet somewhere, potentially StackOverflow. I will credit the author once I know/remember who it is.
public static class SerializerHelper
{
/// <summary>
/// Serializes an object.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="serializableObject"></param>
/// <param name="fileName"></param>
public static void SerializeObject<T>(string filepath, T serializableObject)
{
if (serializableObject == null) { return; }
try
{
XmlDocument xmlDocument = new XmlDocument();
XmlSerializer serializer = new XmlSerializer(serializableObject.GetType());
using (MemoryStream stream = new MemoryStream())
{
serializer.Serialize(stream, serializableObject);
stream.Position = 0;
xmlDocument.Load(stream);
xmlDocument.Save(filepath);
stream.Close();
}
}
catch (Exception ex)
{
//Log exception here
}
}
/// <summary>
/// Deserializes an xml file into an object list
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="fileName"></param>
/// <returns></returns>
public static T DeSerializeObject<T>(string filepath)
{
T objectOut = default(T);
if (!System.IO.File.Exists(filepath)) return objectOut;
try
{
string attributeXml = string.Empty;
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.Load(filepath);
string xmlString = xmlDocument.OuterXml;
using (StringReader read = new StringReader(xmlString))
{
Type outType = typeof(T);
XmlSerializer serializer = new XmlSerializer(outType);
using (XmlReader reader = new XmlTextReader(read))
{
objectOut = (T)serializer.Deserialize(reader);
reader.Close();
}
read.Close();
}
}
catch (Exception ex)
{
//Log exception here
}
return objectOut;
}
}
Before I get to the usage examples, some tips so you know how to approach this:
These methods will serialize a single object (of any type) to a given file. This can be a class Foo, a List<Foo>, or a custom made class that contains all the data you want to save MyFooData
You cannot add to an existing file. When saving a file, the old file will be overwritten. I have not yet come across a use case where I needed to add to a file and couldn't just read the file's contents, change them, and store the whole object again. But I've only used it for small scale storage.
XML serialization uses public properties and a parameterless constructor. So make sure the objects you want to store have both of these. It will not serialize private or protected properties; or public/private/protected class fields.
The XML Serializer will automatically also serialize subclasses that are contained within (if they are public properties!). As far as I'm aware, it can go as deep as you want it to go. It will save everything.
The XML serializer has a weakness to recursion. I will explain how to avoid recursion in the code examples.
XML Serialization cannot (de)serialize Dictionary<T1,T2> or any IEnumerable that uses hashes for storage. However, if you want to store a Dictionary<T1,T2>, you can store it as a List<KeyValuePair<T1,T2>>, which means it will retain your data; just not the internal hash that it uses for quick lookup.
1 - The simplest example
[Serializable]
public class User
{
public string Name { get; set; }
public string Email { get; set; }
}
public static void TestMethod()
{
var myUser = new User() { Name = "John", Email = "John#john.com" };
//Save to file
SerializerHelper.SerializeObject(#"C:\MyDir\MyFile.txt", myUser);
//Read from file
var myUserReloaded = SerializerHelper.DeSerializeObject<User>(#"C:\MyDir\MyFile.txt");
}
Take note of the [Serializable] attribute on the User class. This is usually the only change that you need to make to your classes to make this work.
2 - Avoiding recursion and stack overflows
As mentioned in the tips, this serialization has a weakness to recursion. This can happen when classes refer to eachother in both directions.
[Serializable]
public class User
{
public string Name { get; set; }
public string Email { get; set; }
public Manager Boss {get; set; }
}
[Serializable]
public class Manager
{
public string Name { get; set; }
public User FavoriteEmployee {get; set; }
}
public static void TestMethod()
{
var userJohn = new User() { Name = "John", Email = "John#john.com" };
var managerMark = new Manager() { Name = "Mark" };
managerMark.FavoriteEmployee = userJohn;
userJohn.Boss = managerMark;
//Save to file
SerializerHelper.SerializeObject(#"C:\MyDir\MyFile.txt", userJohn);
//Read from file
var userJohnReloaded = SerializerHelper.DeSerializeObject<User>(#"C:\MyDir\MyFile.txt");
}
You will get a stack overflow exception when saving the file, because the serializer gets stuck in an infinite loop.
The serializer tries to write all of userJohn's properties to the file. When it gets to the Boss property, it notices that it is a serializable object and will begin serializing all of managerMark's properties. When it gets to the FavoriteEmployee property, it notices that it is a serializable object and will begin serializing all of userJohn's properties. When it...
You can prevent this from happening by using the [XmlIgnore] attribute on one of the two properties (or both, if you want to be really secure).
[Serializable]
public class User
{
public string Name { get; set; }
public string Email { get; set; }
public Manager Boss {get; set; }
}
[Serializable]
public class Manager
{
public string Name { get; set; }
[XmlIgnore]
public User FavoriteEmployee {get; set; }
}
The serializer tries to write all of userJohn's properties to the file. When it gets to the Boss property, it notices that it is a serializable object and will begin serializing all of managerMark's properties. When it gets to the FavoriteEmployee property, it notices that this property is marked [XmlIgnore] and it will not attempt to serialize what is contained within.
I hope this answer is what you were looking for.
EDIT I forgot a big caveat.
Let's say we are storing a List<Child> with two Child objects in it. Both Child objects have a Parent property, and it just so happens that both children are referencing the same Parent (same object in memory).
If I store the Parent (including a list of its children) it will serialize our Parent which will contain both Child objects. When deserializing, you will again have a singular Parent object and the two Child objects you started with.
If I store the List<Child> (including their parent), it will serialize the Parent for both Child objects. However, when deserializing, both Parent objects will be deserialized but they will be separate objects in memory.
As you can see, there could be a potential bug here if you are expecting both children to refer to the same Parent (as an object in memory). For this reason, I have a personal rule about how to use the serialization, and where to put the [XmlIgnore] attribute.
Children (IEnumerable<Foo>) get serialized, parents (Foo) do not. This allows me to store an entire tree in one go.
This means that I have to store the parent (and automatically have its children be serialized too), and I can only store the child without its reference to its parent (unless you store a ParentId key in the Child).
By doing it this way, you ensure that you won't create a multitude of Parent objects through deserialization, because every object only gets mentioned once in the XML file.
Edit
I forgot to add the SerializerHelper. to the method calls. Fixed now.
I want to create a WinForms application.
This application will have many configurable options that will be saved in a database, so they can be persisted across executions (e.g. print settings, design options, etc.).
What approach would you recommend for loading these options, to avoid frequent access to the database?
Thanks!
If it security isn't important, you could also have the settings saved in an xml file that your form reads in. You could have a class that loads the properties that you need.
http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlserializer.aspx
[Serializable()]
public class Defaults
{
public string Description { get; set; }
public double Tolerance { get; set; }
public string Units { get; set; }
}
internal class FormDefaults
{
public void LoadSettings()
{
string kfileString = #"C:\Default_Settings.xml";
var q = from el in XElement.Load(kfileString).Elements()
select new FormDefault()
{
Description = el.Element("InstrumentDescription").Value,
Tolerance = Double.Parse(el.Element("InstrumentMassTolerance").Value),
Units = el.Element("InstrumentMassUnits").Value,
};
}
}
}
That's pretty rough but I had something similar that worked pretty well and was pretty easy to set up.
Cheers
There are some problems, the settings saved in the database will be shared by all the users. In this case you have think about having settings for each user. Better option would be saving in the local config file which can be encrypted and used. If anything needs to shared across users then can use db for that particular option. You can load those option before application loads and access it through objects.
You can do these database fetch operations in the SPlash screen by showing progress to the users.