Long story short, the .Net ConfigurationManager.GetSection method skips duplicates, and I'm looking for a best practice for handling this. I have a config file that includes something like this:
<views>
<view name="BusinessUnitsView" Desc="desc1"/>
<view name="BusinessUnitsView" Desc="desc2"/>
</views>
I have a graph of objects the config loads onto where collections derive from our derived version of ConfigurationElementCollection. The views collection in the graph only has one item in it after loading the above--my understanding is that this is simply the way the ConfigurationManager handled duplicates. The last item with the same key wins.
I could throw an exception on a duplicate being found by using BaseAdd(element, true). However, if possible I'd like to get the object completely loaded WITH duplicates, as the config gets read in a service layer, and I'd like to detect and deal with the problem on the consuming side of the service.
Do I have any options for modifying the way adds to the collection work?
You will need to create your own ConfigurationSection. See here or here (the second link's method has been deprecated, but it may still shed some light)
This allows you to represent internal configuration variables as collections, and set properties like DefaultValue and IsRequired.
Maybe you only want to iterate over a list but the main idea of the config is that you can do
var view = SomeConfigClass["BusinessUnitsView"];
That only allows one answer.
Related
I have a variety of methods that use a configuration object to fill in placeholders in a template. Different methods use different subsets of properties of the configuration object. I'd like an easy way to check that all the properties a given method uses are present in a given config object.
Right now I have a method like this:
private static void ValidateConfiguration(CustomerConfiguration config, params string[] properties)
This has the maintenance disadvantage that it relies on a separate set of strings for the properties used. What I'd love to do is have the validation method look at the calling method and see what properties of the config object are being accessed. Can this be done?
(I could also wrap String.Replace() in a method that checks for nulls, but that's less fun.)
A type safe way to handle your problem would be to implement several interfaces with different meaningful subsets of properties. My understanding is that the presence/absence of the properties in your case depends on the type of configuration object and is dynamic.
you could use a signature like that
ValidateConfiguration<T>(CustomerConfiguration config)
where T represent the interface and use reflection to list the required properties. While it would be practically impossible to parse the code of a method to infer its usages of a data structure, reflection on types (to extract properties) is fairly easy.
Different methods use different subsets of properties of the configuration object.
If you're only creating one instance of the configuration property, then the properties it needs to have are whichever ones are going to be used by any method. In other words, if at least one method needs that property, then the object needs that property.
In that case there's no need to validate it in relation to individual methods that need it. All of its properties need to be populated because they're all needed somewhere. If they're not needed anywhere, you can delete them.
Then, instead of validating that object based on the needs of a particular method, you validate it once, perhaps at startup. All of the properties are needed, so if they haven't been specified then the application just can't run. (Sometimes it's good to include defaults in your configuration object. You might have one property that you want to be able to configure, but in real life it's never going to change.)
If you're creating different instances of the same object for use in different methods and you only want to populate certain properties then it's better not to do that. Just create more granular objects for different scenarios containing all the properties you need.
What frequently happens is this: We have an object with lots of properties and we only use a few of them, so we populate those properties and pass the object to a method. The other properties are null.
Then, someone modifying that method decides that they need another property, so they try to use it, and they're surprised to find out that it's null. Then they have to go back and trace where that object was created and figure out what is populated or not. That's confusing and time-consuming.
Unless fields are entirely optional and it doesn't matter whether they are populated or not, we don't want to find ourselves looking at an object with lots of properties and guessing which ones have been populated because individual methods that create the object "know" which properties other classes do or don't need.
I am building web service in C# for a particular application, I have a XML definition of module. I have created a class called Field that holds the properties of all fields on a module. What I would like to do is create the field objects but name them dynamically then add them to a list of some sort. So when I reference them from the client it would be like this:
Module.Fields.MyDynamicName.FieldProperty
Is this possible to do? and could anyone point me in the right direction on how to do this.
Hope my question makes sense.
Basically you need to design for "deferred design", which means you do not know at compile time what the design is, but you still need to accommodate it.
There are probably a few ways but what I have done in the past is use a dictionary list of Key/Value pairs to store fields. Using serialization (I prefer Json) you can shove just about anything into a string and store it as the Value, then deserialize it when you need it.
I need to be able to validate some business rules on entities before any modification to DB is performed (Create, Update, Delete), and throw exception and rollback if these rules fail. I am building a framework and I want to do that always, despite whether user use my class to modify entities or directly NHibernate Session. I also need to be able to customize these business rules, depending on configuration file.
I've tried to inherit DefaultSaveOrUpdateEventListener, overriding PerformSaveOrUpdate, PerformUpdate, PerformSaveOrReplicate, PerformSave, OnSaveOrUpdate and DefaultSaveEventListener with overriding PerformSaveOrUpdate, PerformSave, PerformSaveOrReplicate, PerformUpdate, OnSaveOrUpdate. I just put Debug.WriteLine, and called the base implementation. I didn't find any good and detailed description of those, so I tried everything that seems like what I need.
And I have initialized them like this:
configuration.EventListeners.SaveOrUpdateEventListeners[0] = new SaveOrUpdatePermissionListener(_mappingContext);
configuration.EventListeners.SaveEventListeners[0] = new SavePermissionListener(_mappingContext);
But looks like this does not always work. If I modify objects in the object tree, for some reason these methods catch all objects except of the root object.
What I did wrong? Maybe there are better ways of doing what I want to do?
Was able to do that, by inheriting IPreUpdateEventListener, IPreDeleteEventListener, IPreInsertEventListener interfaces instead of DefaultSaveOrUpdateEventListener and DefaultSaveEventListener.
Still, if anybody has a better idea of achieving the task, I'm eager to listen.
I oftem run into this case of what is the correct way to store a list of objects as a property in a class and how to properly serialize them into XML.
For instance, we have a TabGroup class which will contain zero or multiple Tabs.
Is it better to a have a list of Tabs property or a list of references to Tabs? Provided that Tabs are identified by slugs which are unique.
List<Tab>
List<string>
In the end it comes down to
Serializing only the whole TabGroup graph (which will contain all its Tabs and their content)
Serializing Tabgroups and Tabs indenpendently and maintaing them separate and referenced through list of slugs in the serialized Tabgroup graph.
Most notable pro of 1:
Tabgroup in its entirety is persisted in one serialized file, keeping the datastore structure simple.
Most notable con of 1:
each time an update is made to one of the contained Tabs, Tabgroup must be updated (reserialized) too.
Most notable pro of 2:
updating tabs does not require reserialization of Tabgroup (at least when nothing was added or removed) since the references stay the same; so only the updated Tab has to be serialized again.
Most notable con of 2 (this is the main reason why I am writing this)
individual Tab files can be deleted in filestore but list of references remains the same, so errors/exceptions occur when viewing/rendering Tabgroups; complex logic would have to be implemented to render out something like "Tab was removed from datastore in unsupported way, remove it from the Tabgroup also?"
What do you suggest to tackle this problem? I will accept the answer that will cover a wide array of implications. Please note that we are talking only about XML persistence here, obviously in SQL we have little room to experiment since Tabgroups and Tabs would normally be in separate tables anyway (with a one-many relationship between them).
Unless you have some very compelling reason why complicating the data store is a good idea, you should typically go with keeping it simple. Secondly, having read the entire post twice, I do not really understand what your question is.
I'm not quite sure what your problem is, but if you are asking whether your design should return a List<Tab> or List<string> where each string represents a link to a tab, then I would argue for List<Tab>. You can lazy load the entire structure except for the ID or whatever you were using for a link if loading is an issue. Generally it just makes things easier to get what you were looking for directly out of an object instead of having to get a list of links and load all of the links individually.
Without more information specific to the actual problem, I doubt anyone would be able to help you more than that other than to give some long winded pros/cons based on assumed circumstances.
i'm kind of stuck here. i'm using a dragndrop-library which serializes the dragged UIElements via XamlWriter.Save().
now i'm trying to dragndrop some instances of a class extending Grid. in the constructor i push some elements into the visual tree.
the constructor gets called when the object is deserialized and the elements get added again (and again and again depending on how often i dragndrop). sadly Children.Count tells me there are no child elements if i retrieve the value from within the constructor. if i retrieve it from outside (by myGrid.Children.Count) it gives me the higher (unwanted) amount.
is there any other function i should use to initialize the visuals? or any other way to prevent those duplicates?
thanks and cheers
took a while, but i seem to have found a solution.
now i'm able to create a base class already containing the visual elements all the subclasses need. and they are parsable via XamlWriter/Reader without duplicates. whew.
1) extend UserControl (dont Add->UserControl but Add->Class and inherit manually)
2) put the standard InitializeControl(); into the constructor
3) implement InitializeControl() and put the layouting, child adding and whatever in there
4) xamlwrite/xamlread/inherit like crazy
hope it will be helpful to someone and that i havent overseen the unforeseen..
--
edit: of course.
there will be duplicates but we cant see them.
after the XamlReader is through there are the UIElements created by my InitializeComponent() AND the ones getting xaml-parsed after that. any references in the code regard the code-created controls which are NOT show :/
sigh.
one far from perfect way around this is to put a switch into an Initialized event handler, like so:
if(HasContent)
Initialize();
else
Reinitialize();
Multiinitialize();
where the Initialize() would add the UIElements to the visual tree, the Reinitialize() just finds the right references (by control = FindName("controlName")) and the Multiinitialze() recreates the event handlers and what else gets lost on the way throug the XamlReader.
well, now you can instantiate the custom inherited UserControl in xaml but there is no easy way to set attributes. that is because setting the attributes happens before the Initialized-event and there are NullPointerExceptions awaiting. you could work around that with bindings i guess.
but there HAS to be an easier way. please let me know!