I'm trying to come up with a generic model for associating some contextual data with an object in C#. I have built a caching system that can be described as follows...
Background Story -> The cache is a singleton implementation that provides "readonly" access to frequently requested information that is part of a custom CMS implementation that I use for various asp.net applications. I update the data via a desktop application I have written and the next time the web server loads the cache my changes are reflected to visitors.
My cache adheres to the following...
Every object has a unique id
Any object can be associated with any other object by an id mapping defined in an association table
No matter how many associations to a particular object exist, only one instance of that object is loaded into the cache.
For example...Object A might associate to a collection of Object C's. Similarly Object B might also associate to a collection of Object C's. If one were to request an Object C with id 23 from an instance of Object A and then request an Object C with id 23 from Object B, they would get a handle to the same instance of Object C.
I now have some data to add into the picture but the data does not belong to Object A by itself and it does not belong to Object C by itself. The data is information specific to the association of Object A with Object C.
My First Idea: Keep the additional data separate from Object C since it doesn't actually belong to Object C by itself. Maintain this information within Object A and allow it to be looked up in a Dictionary. I don't like the way the data has to be accessed in this approach. I would rather have direct access to the additional data via Object C or a derived class for binding purposes and ease of use.
My Second Idea: Create a derived class from Object C (call it Object D) that includes the additional contextual data and provides properties for easy access. This addresses the binding and gives me the ease of use that I was looking for. My problem with this approach is that now my Object A is referring to a collection of Object D's and I am required to break my above model by duplicating the entirety of Object A's data just so that I can append some extra association information.
What I would really like is to continue having only one instance of Object C for a given id and append some contextual data and properties that can be easily accessed in the appropriate context. Can this be done? I'm also open for any other suggestions here! I want my solution to be generic and sound so I can forget about it and not have that constant itch to go back and find a better solution.
The Objec C instances should hold there own data. Of course you can store the "path" in it via what the object was retrieved from the cache (via Object A or Object B), but storing this kind of information in the object, modifies the object, so if it were to be retrieve via another "path", the information will be overrwritten.
A solution could be to clone object C every time it is retrieved from the cache and store your "path" in it, or store your extra data if it came via Object A?
This way, all objects inside your cache are shared as requested, but stand alone once outside the cache.
I ended up going with my second idea. Object D became a special type of object that has it's own properties/members/methods but also has a property that returns an Object C. Object D must implement a specific interface to be identified by my caching algorithm. I updated my caching system to ensure that if the Object C returned by the property has already been loaded, that one is returned instead of loading up an additional copy from the db.
Related
I'm using ObjectListView and the object I'm adding to it is a custom Class that I've built for it.
My Class contains information for doing calculations. I want to allow users to be able to edit calculations they've already made.
I've tried pulling the object from the ObjectListView with the following different code:
Customer customer = (Customer)listCustomers.SelectedItem.RowObject;
Customer customer = (Customer)listCustomers.GetSelectedObject();
Customer customer = (Customer)listCustomers.SelectedObject;
All of those methods result in the customer to become that object. The problem I'm facing though, is if I change any of the values of that class, such as the following code, it reflects the change in that object in the ObjectListView:
customer.TotalValue += 50;
And even if I run those calculations on another form, by transferring that information via:
EditCustomer editForm = new EditCustomer(customer)
editForm.Show();
It still changes the object in the ObjectListView.
What I'm wondering, is how can I extract that object, and allow me to edit the customer object, while not changing the object in the ObjectListView?
Your customer variable is a reference to the object stored in your ObjectListView, so when you modify customer, the change is reflected in the underlying object it is referencing. When you pass customer to a different form, you are passing the reference, still pointing to the same underlying object, so that object can then be modified through that reference, even from a different form.
To get the behavior you want, you need to clone your object, making a completely separate copy of it, and then making changes to the copy will not impact the original.
Check here for information on cloning objects.
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 write a generic possibility to convert from database object to business object.
My business object contains custom attributes and depending on them, I like to make specific operations on them.
On reading from db its quite easy because I can use aftermap (not perfect solution, cause I have to do it by reflection and set the value depending on it)
But on writing back to the database I have to do it beforeMap but this would change the source permanent, but I just like it in a transient way. So do the operation with Source on the fly but do not change source object.
It's a generic option so I can't work with properties.
protected static T MapFromDatabaseWithConversion<T, TSource>(TSource source) where T : MappingModel, new()
{
var config = new MapperConfiguration(cfg => cfg.CreateMap<TSource, T>().AfterMap((src, dest) => dest.ConvertFromDatabase()));
return config.CreateMapper().Map<T>(source);
}
Do you have any solution for the check on the fly the attribute of a property and change the value depending on it - or you have any idea to change source only on the fly, so not write the result of source operation to src obj?
Thank you very much.
I think you have to include value tracking in your objects. For each class member you would need a boolean to reflect if the value changed, and a method that checks them all at once such as isObjectChanged(). You can hard code this or wrap your object in a Proxy object at runtime, which is more complicated, but does not clutter you class with value tracking data/methods. On the other hand, Java Data Objects (https://db.apache.org/jdo/) can do this for you by re-compiling your class files to include value tracking within the class about changing values. It takes a bit to set up and may be overkill for your specific question, but I have used it many times when targeting multiple data sources in the same project such as a database or spreadsheet. JDO allows me to use the same code with a different data type manager that can be swapped at runtime. You can also target a No-SQL database and other data stores as well.
So essentially I'm making a WPF/MVVM Light application and I currently have a TreeView that represents a variety of different types of objects. Each of these objects is wrapped in a very generic "ViewModel" that currently just exposes their name to the TreeView display in the application.
Linked conceptually to this tree, I want to provide an Object Viewer below the tree, such that when a user selects an item in the three, the object viewer is populated with the Properties of that node and it allows the user to change and save new values to the node in question.
I'm effectively trying to create an abstraction that can take a variety of types (7 different object types) and expose their Properties AND allow the user to edit them. Essentially, I can bind the properties of this abstraction to a group of Text/Display boxes on the UI, and when the user hits save, have it call update methods on the actual underlying data objects from this middle wrapper class.
Currently, the only way I can think to accomplish this is to make a separate wrapper for each underlying object type (since they all have different Properties), and essentially hard-code the fields and update methods.
Are there any other options in terms of providing further abstraction and creating a general wrapper class capable of exposing and updating Properties from a variety of objects? Thanks.
Instead of wrapping every model in a different ViewModel, you may want to expose the model directly to the View and create a DataTemplate for each type of model, this will allow you to have different UIs for each model type without having to place an intermediate ViewModel in between. Just a suggestion.
I have an application that reads a table from a database.
I issue an SQL query to get a result set, based on a unique string value I glean from the results, I use a case/switch statement to generate certain objects (they inherit TreeNode BTW). These created objects get shunted into a Dictionary object to be used later.
Whilst generating these objects I use some of the values from the result set to populate values in the object via the setters.
I query the Dictionary to return a particular object type and use it to populate a treeview. However it is not possible to populate 2 objects of the same type in a treeview from the Dictionary object (you get a runtime error - which escapes me at the moment, something to with referencing the same object). So what I have to do is use a memberwiseClone and implement IClonable to get around this.
Am I doing this right? Is there a better way - because I think this is causing my program to be real slow at this point. At the very least I think its a bit clunky - any advice from people who know more than me - greatly appreciated.
Is there a reason you are using the external dictionary? I would populate the tree directly as the data is queried.
If you do require the dictionary, you could set the .Tag property of the tree node to point to the data in your dictionary.
To add to #Brad, only populate the tree as needed. That means hooking into the expand event of the tree nodes. This is similar to how Windows Explorer functions when dealing with network shares.
There should be 1 TreeNode object per actual tree node in the tree - don't try to reuse the things. You may either associate them with your data using the Tag property (this is the recommended method), or you can subclass the TreeNode itself (this is the Java method, but used less in .NET).
(The use of cloning methods is usually a hint that you're either (a) doing something wrong, or (b) need to factor your domain model to separate mutable objects from immutable.)
have you considered using a Virtual Tree view which only loads the nodes the user actually wants to look at - i've had good success with the component from www.infralution.com