C# how to store parsed data inside application? - c#

This is rather general question, but it relates to overall application design. I'm trying to create application that follows class design standards and I'm struggling with one aspect that is how to store information internally.
For example I can create a class for a Movie with couple fields:
title
year
director
So when I parse xml files that holds this metadata I would load them into a public List. I'm not sure if this is a right approach? Since List is an instance of an object, maybe it does not belong in a class that defines Movie?
It is public list it would be available in other parts of application.
I do not see any point of parsing xml files multiple times during application activity. The same goes for accessing database like SQLite.
I looked at Singleton design and I'm not sure if that is a right approach? Plus based on Singleton samples I viewed, I do not know if I can define fields that I mentioned before.
So, my question is. How do you deal with metadata or file paths from scanned folder? Where do you keep this information inside your application?
Thank you

The class which parses the XML file shouldn't store the result. If that class parses a list of movies, it should just return an IEnumerable<Movie>, and then the caller of that class can store the result wherever it wants to.

This is a pretty general question and there are a number of ways to do it depending on your NFRs. The following is a pretty basic way that should be forward compatible with a number of approaches.
Declare the list within main program scope as an IList<Movie>.
Write a class that implements IList (e.g. class MovieList:IList<Movie>) that exposes the data you need. It can cache it if you want. It doesn't have to. For now, write the simplest code that could work.
Later, in the main program, you can change the declaration of your IList to use an IoC container to instantiate the IList (e.g. _myList = Container.Resolve<IList<Movie>>. That way you can substitute different data providers, or substitute a mock provider for unit testing.
Later, you can change the implementation of MovieList to include caching, or store the data in a DB, or whatever you want. Or you can totally rewrite it in a new class and change the configuration of your IoC container to point at the new class. You will have all sorts of options. (The decision to cache or not to cache will ultimately depend on NFRs such as storage capacity, performance, and concurrency/ACID)
The point is to write down the bones of what your program truly needs, and worry about the details of where and when to store stuff later.
I don't think it is a good idea to simply store the whole list in a global variable without some kind of abstractification.

Related

Is a class full of defined strings normal?

I have a newb question. I have a winforms application that has a number of classes that referenced a number of UNC network paths. I started to notice I had a bunch of string duplication and then started trying to weed them out by consolidating them into the classes that just make more sense to have them. I was then referencing the class with the string I needed each time I needed to get the value of the string but I'm sure this was a sloppy way to do it.
Now I've settled on making a single class ("StringLibrary") and am referencing that class in each class I need to pull strings from. This seems much more efficient than what I was doing before, however, I'm still not sure if this is a good way to do it in general.
Is there a better way (i.e. more standardized way) to consolidate a group of strings or values in c#?
It depends on whether the strings are configuration or more permanent. For network paths, you may want to put them in your app.config file (see What is App.config in C#.NET? How to use it?), since they may change from time to time, or differ between deployments (and you do not want to recompile your code for every site) Depending on the nature of the data, you may alternatively want to store it in the registry or in a database.
If it is something more tightly tied to your code, like names of controls on a form, or names of columns in your database. Then you may want to centralise their definitions as you suggest, and reference them all from there. When there are a lot of them, your may want to split your StringLibrary into more classes with more relevant names (e.g. if you are speficying names of columns in your database, then you may want to create such a static class for each table in your database) If you take this approach, and since you are new to C# it may also help to read Static readonly vs const to decide if you want them to be const or static readonly.
These could be added to an application config file/ web config file,
resource files and/or settings files.
This way you can administer these strings, should they change, without having to re-build your application and also apply transformations (if in an app.config/web.config) when performing releases to different environments/deployments.

How to prevent multiple loads in C#?

I've got a class hierarchy in C# describing some data structure. There are base classes, which automate and perform some general tasks and on top of them there are specialized classes, which reflect the actual structure.
I want that structure to be able to be loaded only once. If you load it - or modify any of its fields - loading should no longer be available.
I came up with three solutions:
Create a flag bool loaded field and set it when class is loaded (or changed).
Pros: Structure does not have to be changed from what it currently is, straightforward usage (new + .Load())
Cons: I would have to work hard to propagate this flag throughout the whole structure and generally take care of it, such that it would be updated in every possible case. Also, this is runtime solution (second load = exception), while I always prefer compile-time solutions.
Move the loading to constructor of class, such that one might create an empty structure or create it and load immediately after.
Pros: Compile-time solution: one would not be able to simply load the structure at any time.
Cons: Loading relies on derived classes and virtual methods cannot be called in the constructor, what complicates things. This can be overcome, but in the cost of simplicity of the interface. Also it happens, that while loading, I have to return a object, what would require the ctor to have an out parameter (that seems to be a necessity anyway).
Create class factory, hide the ctor and provide factory methods for creating empty and pre-loaded structure.
Pros: Compile-time solution. Factory can be generic to cover all derived classes
Cons: Complicated code and non-intuitive interface (factories are a little less obvious way to create things than new operator). Also, this solution relies on internal modifier to make the structure and factory friends.
My questions are:
Is there a better way to prevent one from loading a structure a few times?
Or: is there a way to overcome downsides of proposed solutions?
Edit: In response to answers
Think of my structure as of Word document or Excel sheet. Word document can only be loaded once, you cannot "call load" on already loaded document. This is a kind of security measure I want. In other words I want to prevent someone from calling:
MyStructure s = new MyStructure();
s.Load("file1.str");
s.Load("file2.str"); // Doesn't make sense
And also:
MyStructure s = new MyStructure();
s.SomeProperty = 15;
s.Load("file1.str"); // Doesn't make sense
You should use an Identity Map for that. It keeps track of which entities have already been loaded.
Additional cons:
1 - Your data object is no longer holding just business data - it's also holding a loaded state - this is against the SRP.
3 - Factories may have to change when more types are created - this will mean more maintenance
It looks like you are using the active record pattern. I would not use the active record pattern as it combines business data and data loading - this is against the SRP.
Instead, use the repository pattern with POCOs to create your objects.
However, if you are keeping the current code you could add checks in the Load method - if the file name is different to the current file name (surely a property) prevent the load because it doesn't make sense in this context.
I want that structure to be able to be loaded only once.
Have you looked at the Singleton pattern?
The singleton pattern restricts the instantiation of a class to one object. Using the pattern will ensure you are not re-inventing the wheel.
However, I am not sure if you really only want one object in your application, or you want to ensure your code doesn't retrieve the data more than once for performance reasons - hence two answers.

C# reference collection for storing reference types

I like to implement a collection (something like List<T>) which would hold all my objects that I have created in the entire life span of my application as if its an array of pointers in C++. The idea is that when my process starts I can use a central factory to create all objects and then periodically validate/invalidate their state. Basically I want to make sure that my process only deals with valid instances and I don't re-fetch information I already fetched from the database. So all my objects will basically be in one place - my collection. A cool thing I can do with this is avoid database calls to get data from the database if I already got it (even if I updated it after retrieval its still up-to-date if of course some other process didn't update it but that a different concern). I don't want to be calling new Customer("James Thomas"); again if I initted James Thomas already sometime in the past. Currently I will end up with multiple copies of the same object across the appdomain - some out of sync other in sync and even though I deal with this using timestamp field on the MSSQL server I'd like to keep only one copy per customer in my appdomain (if possible process would be better).
I can't use regular collections like List or ArrayList for example because I cannot pass parameters by their real local reference to the their existing Add() methods where I'm creating them using ref so that's not to good I think. So how can this be implemented/can it be implemented at all ? A 'linked list' type of class with all methods working with ref & out params is what I'm thinking now but it may get ugly pretty quickly. Is there another way to implement such collection like RefList<T>.Add(ref T obj)?
So bottom line is: I don't want re-create an object if I've already created it before during the entire application life unless I decide to re-create it explicitly (maybe its out-of-date or something so I have to fetch it again from the db). Is there alternatives maybe ?
The easiest way to do what you're trying to accomplish is to create a wrapper that holds on to the list. This wrapper will have an add method which takes in a ref. In the add it looks up the value in the list and creates it when it can't find the value. Or a Cache
But... this statement would make me worry.
I don't want re-create an object if
I've already created it before during
the entire application life
But as Raymond Chen points out that A cache with a bad policy is another name for a memory leak. What you've described is a cache with no policy
To fix this you should consider using for a non-web app either System.Runtime.Caching for 4.0 or for 3.5 and earlier the Enterprise Library Caching Block. If this is a Web App then you can use the System.Web.Caching. Or if you must roll your own at least get a sensible policy in place.
All of this of course assumes that your database's caching is insufficient.
Using Ioc will save you many many many bugs, and make your application easier to test and your modules will be less coupled.
Ioc performance are pretty good.
I recommend you to use the implementation of Castle project
http://stw.castleproject.org/Windsor.MainPage.ashx
maybe you'll need a day to learn it, but it's great.

Design Pattern for using XML as a list structure in C#

I am designing a list-based app in C# WinForms where I want to store my data in an XML file (which will eventually get serialized into a database). I have a custom control that displays my list data based on my XML, but I'm having trouble determining the best structure to handle the data. I have a ListManager class that keeps track of an XMLDocument, and has methods like CreateList and AddListItem. Should I be using a local copy of the XML structure as what my UI Control reads from, or should I use the actual XML File itself? Is there something better than the XMLDocument that I should be storing as a member variable to keep hold of the data?
Also, how should I go about linking the controller with the UI control? In other words, how should my ListManager alert the ListControl when a new item was added? (Or should it not be doing the update notification at all, and instead the Main Form should do that?)
Thanks!
I would create a custom class to hold my data using strongly typed collections such as the generic collections System.Collections.Generic.List. Then, you can just serialize this class to and from XML on the client until you are ready to push the content into a database. Using serialization means you can work with plain old C# objects instead of trying to shoe-horn the XMLDocument class into your business object.
Take a look at this article for some details on how serialization works.
imho the scenario you describe could lend itself to several strategies, and key criteria for which implementation strategy you choose might be the dynamic nature of the "data flow," and the sheer size of the data you are handling.
If you are describing a situation where you are dealing with vast stores of data, so that you will not be able to maintain "entire" the internal representation of the external file because of memory constraints : that's one case : in that case you will require "virtualisation" in the sense of that word used to describe presenting "partial views" of the data at any one given moment in time, and, probably, caching so that you keep as much data as you can "ready to display." Or you may elect to use another control for display (like DataGridView) which has "virtual partial display" built-in.
If you are dealing with "asynchronous flows" of new data being added, existing data being removed or edited, hundreds (or thousands) of times per minute, in any order (perhaps from multiple users ?) that's another case.
So, when I suggest you to consider a strategy where :
the ListManager raises custom events to notify subscribers of data change
the custom control (that we assume handles presentation) subscribes to the events of interest raised by the ListManager class, and "does the right thing" : which might involve requesting another "serving" of data from the ListManager, or whatever, to make the current presentation up-to-date.
Please consider that may reflect the simplest possible scenario.

C# Console App Session/Storage

What would be the best way to implement a psuedo-session/local storage class in a console app? Basically, when the app starts I will take in some arguments that I want to make available to every class while the app is running. I was thinking I could just create a static class and init the values when the app starts, but is there a more elegant way?
I typically create a static class called 'ConfigurationCache' (or something of the sort) that can be used to provide application-wide configuration settings.
Keep in mind that you don't want to get too carried away with globals. I seriously recommend taking a look at your design and passing just what you need via method parameters. You're design should be such that each method receives a parameter for what is needed (see Code Complete 2 - Steve McConnell).
This isn't to say a static class is wrong but ask yourself why you need that over passing parameters into your various classes and methods.
If you want to take the command line arguments (or some other super-duper setting) and put them somewhere that your whole app can see, I don't know why you would consider it "inelegant" to put them in a static class when the app starts. That sounds exactly like what you want to do.
you could use the singleton design pattern if you need an object that you can pass around in your code but imo a static class is fine, too.
Frankly, I think the most elegant way would be to rethink your design to avoid "global" variables. Classes should be created or receive data they need to be constructed; methods should operate on those data. You violate encapsulation by making global variables that a class or classes need to do their jobs.
I would suggest possibly implementing a singleton class to manage your psuedo-session data. You'll have the ability to access the data globally while ensuring only one instance of the class exists and remains consistent while shared between your objects.
MSDN implementation of a singleton class
Think about your data as a configuration file required by all your classes. The file would be accessible from every class - so there is nothing really wrong with exposing the data through a static class.
But every class would have to know the path to the configuration file and a change of the path would affect many classes. (Of course, the path should better be a constant in only one class referenced by all classes riquiring the path.) So a better solution would be creating a class the encapsulates the access to the configuartion file. Now every class can create an instance of this class and access the configuartion data of the file. Because your data is not backed by a file, you would have to build something like a monostate.
Now you could start thinking about class coupling. Does it matter for you? Are you planning to write unit test and will you have to mock the configuration data? Yes? In this case you should start thinking about using dependency injection and accessing the data only through an interace.
So I suggest using dependency injection using an interface and I would implement the interface with the monostate pattern.

Categories