QUESTION: How can I instantiate a model based on a config file?
BACKGROUND: I have a model simulator application consisting of dozens of different types of objects, each composed of other objects (in a complex compositional hierarchy). I would like to be able to instantiate the model based on an external configuration file. Is there a "standard approach" for this sort of task?
So for example, if I had a config.xml file like this:
<site>
<facility name="F1">
<tank name="t1"/>
<pipe name="p1"/>
</facility>
<facility name="F2">
...
I want a Configurator that can parse that file and create a Site object composed of a collection of Facility objects composed of various Tank & Pipe equipment, etc. (Eventually I will also do this in reverse to persist the model.) The model configuration will change frequently; users will collect many different versions of the config file.
Here are some options I've seen suggested, but I haven't used any of these tools much yet, and I'm hoping to get some advice as to which (if any) of these approaches might be most appropriate for this problem.
Role my own xml config file, parse it using XmlTextReader, and instantiate the model using reflection to map strings to types. (But is this re-inventing the wheel?)
Use ConfigurationManager from System.Configuration, storing settings in app.config. (But not sure how to support the "many different versions of the config file" requirement.)
Use XmlSerializer. (But I understand this requires default constructors, which would rule out constructor-based Dependency Injection which I had hoped to use.)
Use an IoC Container. (But I have several inexperienced programmers who will be interacting with the program; I'd rather not overwhelm them with unnecessary complexity.)
(Bottom line: I hope to "do the simplest thing that could possibly work". But my unfamiliarity with these tools prevents me from determining which one is simplest.)
Option 1:
#JohnSaunders says that a specific way to create a XmlTextReader is deprecated, not XmlTextReader per se. That's true. See here:
http://msdn.microsoft.com/en-us/library/9khb6435(v=vs.110).aspx
While a long list of cases is one option, one would probably not create such a knot in the code. Alternatives:
factory objects that register themself with a key to be used in the XML to identify the factory object
using a type name in the XML and working with reflection:
http://msdn.microsoft.com/en-us/library/vstudio/f7ykdhsy(v=vs.100).aspx
Option 2:
I can't see how saving the configuration in app.config instead of some other XML file relates to or solves your original problem.
Option 3:
Then don't scatter the serialization code.
Option 4:
How about looking into the source code of a not so big DI Framework to get ideas how to do it then?
HTH
Related
Assuming that I'm using no ORM, and following DDD, consider the following case:
A Project has a set of Files.
I've created both a Project and a ProjectRepository and a File and a FileRepository classes.
My original idea was having all the File entities for a given Project being passed to it in its constructor. This Project instance would, of course, be created through the ProjectRepository.
The problem is that if I have a million files (and although I won't have a million files, I'll have enough ones to make this take a while), I'll have to load them all, even when I don't really need them.
What's the standard approach to this? I can't think of anything better than to pass a FileRepository to each Project instance.
Since you mention DDD: if there are two repositories it indicates that there are two Aggregate Roots. The whole point of the Aggregate Root concept is that each root is responsible for its entire object graph.
If you try to mix Files into a Project object graph, then the ownership of the Files is ambiguous. In other words, don't do this:
project
- file
- file
- file
Either treat them as two (associated) object graphs, or remodel the API so that there's only a single Aggregate Root (repository).
There is no standard way. This is domain driven design, so it depends on the domain, if you ask me.
Maybe you could add some more domain to your design.
You only have two concepts: a Project and a File. But you say you don't want to load the file (assuming that File will always load the content of the file).
So maybe you should think about a FileReference, which is a lightweight representation of a file (Name, Path, Size?).
For me it sounds like your problem is the handling of a large set of files and not OOP.
You could implement a service layer which your clients interact with which co-ordinates the repositories and returns the domain entities. This would provide a better separation of concerns; I personally don't think that your client should have access to your repositories.
There's a large WPF application with several modules, windows, self-written controls, etc.
We need to persist state for some of elements of user interface. For example:
windows layout;
controls layout;
last accepted input;
various grids' state(columns' visibility, width, order)
.Settings file seems too plain for this because of no hierarchy in it.
Why can't I just serialize some SettingsModel, containing everything I need and then restore it on application startup?
The very important requirement for persistence mechanism is that it shoud be extensible: If I refactor settings structure, and will try to de-serialize the file created with some previous version of SettingsModel class, I will obviously fail.
So the quiestion is: are there any frameworks for persisting complex settings?
As Rachel suggested, you could use XML serialization, i for one always use that for settings, it has some tolerance for changes but i do not know if it would fit all your needs.
The .Settings file supports changing the structure over time. You don't even need to use the Settings.cs file you can make your own settings providers and have them populate from the config file, each with their own customized Upgrade method to handle changes in the structure.
app.config is another common storage location. Config file settings can be accessed easily from the application and you can even build your own custom configSections
I've done this by writing my own serialization code to XML, labeling the elements to match the configuration fields. When I deserialize, I query the XML for each element I want to populate. If I'm deserializing an old version into a new config scheme that has additional elements, the XML query returns null and I instead insert a default value. It lets me handle lists of hierarchical data, I can encrypt any portion of it I need, and I don't version the XML. Although its a bit more work than using XMLSerializer, my config data doesn't change very often so it was worth it.
Since you can have lots of users, you can save each user's XML as a string in a database. System.Data.Sqlite, RaptorDb, and FileDb work well for this, as does PersistentDictionary.
Yet another alternative is to store your data in dictionaries of dictionaries and use SharpSerializer to save it as XML to either a file or one of the above databases.
OK, so this is not the most useful question since I can't remember the feature in .net that does this. Basically, that's what I'm asking; what feature is this?
A year or so ago, I was working on a project and we used configuration files that mapped directly to a class using the specific attributes on the class members. This is not the standard app.config, but assemblyname.dll.xml instead.
Perhaps it's a feature within the unity framework? Just a stab in the dark.
It is not critical I figure this out today, but it is just weighing on my brain and annoys me that i can't remember!
thanks!
It's not the standard XML config, but it is built into .NET. Basically, XML serialization allows you to project an XML document from a hydrated class instance, that will map 1:1 to the class it came from and can be used to re-hydrate a new instance of that class.
This can, in the majority of cases, be done without much effort on your part. All that's usually necessary for XML serialization to work is that the object must have a public default constructor, and that all the state information you want to serialize must be public and read-write. In a few cases, some attributes are necessary to define certain behaviors, like derived classes in arrays of their parent class, and defining non-default names for field and property element tags.
One of the major uses of this is for custom configuration files as you stated; you can load the configuration from a persistent state by simply deserializing the file into an instance of the configuration object.
Article: MSDN How To Serialize an Object
This isn't part of the .Net bcl or Unity as far as I am aware. Perhaps it's some other third party or open source component? That being said, it wouldn't be too difficult to build something like this on your own using XmlSerialization.
.net allows for multi layered configuration.
Every machine has the machine.config file. each application has the app.config file (which gets renamed to applicationname.exe.config upon building), but each dll can also have it's own config file. so, if I have the following binaries in my executable folder:
flexitris.exe
flexitrisHelpers.dll
thirdPartyContent.dll
each of them can have their own config file:
flexitris.exe.config
flexitrisHelpers.dll.config
thirdPartyContent.dll.config
and all of them will be read at runtime and accessible using the normal System.Configuration namespace.
We have lot of configuration files used in our application. Atleast 100 different xml files for each customer containing at least 50-80 name/value pairs of configuration and all they are often change (atleast every month).
The configuration file looks something similar like below,
<property id="url" value="s123"/>
<property id="input-element-name" value="name" />
<property id="input-element-xpath" value="//body;//form;//table[3];" />
Currently to read this values from xml file we use XmlReader et al and store it in a cache once the application starts (and this could be huge tomorrow when our customer base increases). To access the property ids we have created const variables in a static class to avoid typo etc.,
This approach was great when we had less configurations. Now, it is painful to maintain and add any new to this configuration file. Need to do rebuild etc., just kills the concept of keeping configurable values outside code.
I was just wondering if any recent developments in .NET space such as M language, IronPython could help here to have dynamically typed and compiled configuration values on demand when configuration file gets changed. We don't have any reservations in having xml format for configuration.
In summary, what I need is to have some .XXX files having our configuration values and if anything is changed or added that should be automatically compiled and can be used in our application without creating constants etc., I know something similar happens with .T files in VS.
I hope this could be doable ..
UPDATE
The idea of this question was not seems to be understood correctly or I wouldn't have spelled out correctly. Sorry for the trouble.
The custom configuration section may not appropriate for this problem, the reason is using ConfigurationSection requires code modification if I add any new name/value pair. However, this approach will work if only change values as name part is being mapped to property in the code.
I was wondering if i use any dynamic language breeds such as IronPython or M Language I could be able to move all XML to it and in my application I would able to see any changes to this file (using `FileSystemWatcher') and execute it to read the newly added configuration name/value pairs.
You can implement as many custom ConfigurationSections as you'd like.
This will allow you to model your configuration model as strongly typed objects.
I've used this typed configuration class from Rick Strahl - it worked very well for me.
Vadi, the purpose of external configuration is to obviate the need to recompile for configuration changes.
If the xml you present is representative of the type of information you need to use, a custom ConfigurationSection would serve you nicely and provide the type safety you want.
Please look at the classes in the System.Configuration namespace. They have been there since .NET 2.0, and give you strongly-typed access to XML configuration files, complete with validation.
Could someone tell me the advantages to using the ConfigurationManager class which load's a config file for manipulation VS an XML file with a class you build to read it yourself?
Recently, I built a class which inherits from ConfigurationSection in order to manipulate a custom section within app.config. This was quite a bit of work compared to just opening and reading an XML file.
Some people chose the first approach, others chose the second.
What's good practice?
This is an old question, but what the hell... so yes, there is quite some code overhead in writing configuration sections and elements, but what you get as compared to using your own class with an XML serializer include:
Type conversions and validations: if one of your configuration settings is, say, a "Type" (maybe you store in your configuration what kind of implementation you need to create for some provider), then the ConfigurationManager will not only convert whatever was written in the .config file to a System.Type, but you can also add validation attribtues on your ConfigurationElement's property, like "SubclassTypeValidatorAttribute", which will check that the given type derives from your base provider class/interface. You can of course add your own validators, so that in the rest of your code, you just "get" the configuration and you know everything's valid.
Multi-level settings hierarchy: you can play around with storing settings at the machine, application or user levels, which gives you a mechanism to handle default vs. user-specific settings. You also have APIs to load configurations from custom locations.
No duplication in config files: if you're using other .NET features like TraceSources and stuff, the configuration for that is already in the .config file (say you're troubleshooting a problem and you want to turn on some debug trace that's off by default... you do that by just modifying the .config). If you're using your own config file for your custom settings, then you end up with 2 configuration files, which is not so good.
There's probably other benefits, but that's what comes to mind so far.
It's just a recommended and easier way of reading and writing data to configuration files. Using XML DOM is too low level.
You can always get raw xml configuration from ConfigurationSection using section.SectionInformation.GetRawXml() if needed. Likewise use SetRawXml to set this.
There are a few gotchas though when using ConfigurationManager, for example when you load a config file using OpenMappedExeConfiguration, you get an in memory configuration which is "merged" and has sections from machine.config. You can check if a section came from the file you provided using section.ElementInformation.Source.Equals(source.FilePath).
Reference: MSDN