Lately I have had about enough of creating ViewModel boilerplate code, so I ended up adding the NotifyPropertyChanged-functionality to a DynamicProxy-based solution.
In order to have all of WPF's Changenotification mechanisms working for my implementation, all I have to do now is exchange my Collections with ObservableCollections, which unfortunately brings along a performance issue (change notification for every record added / removed, so not fit for bulk usage because UI gets way too busy trying to keep up with the list of changes).
Thus, In my models, collections of other models (HasMany relationships, that is) are not held within a list, but within a ObservableCollection-derivate that has two Methods SuspendCollectionChangeNotification and ResumeCollectionChangeNotification (A bit like the implementation shown here).
The infrastructure is all there, now I'm looking for an Interceptor hook that enables me to call Suspend() before NHibernate Loads Child data and Resume() after it's done.
I'm a bit afraid I will end up adding this to the proxy I mentioned above, which has a good grasp of the properties that are being requested, but it would be just lovely to keep this in an NHibernate Interceptor...
NHibernate has IInitializeCollectionEventListener which gives you InitializeCollectionEvent when it is loading a collection.
You can hook up like this:
var listener = new YourCollectionListenerImpl();
configuration.SetListener(ListenerType.LoadCollection, adapter);
Unfortunately this only tells you that collection loading is taking place. I don't think it is possible to determine when it is starting and when it has finished.
Related
I am doing something I have never tried before. I am trying to create dynamic UI and bind it to a dynamic model. In other words, my web service is going to send back a small metadata description of my UI and the raw data to bind to it. Therefore, at build time, I don't know what UI I will be constructing and I don't know what my model will be. Binding them together seems VERY difficult if not impossible.
Mvx allows me to bind UI directly to a model WITHOUT it being an MvxViewModel. However, if I bind directly to the Model returned by the web service, I lose the ability to RaisePropertyChanged() since that only comes from MvxViewModel.
Normally, I would write a ViewModel that wraps the Model and have all the wrapped setters call RaisePropertyChanged(). However, in this case, my model is dynamic so I can't wrap it with a ViewModel at compile time since I don't know what it is until runtime.
Is there some cool trick I can use to construct a ViewModel that can wrap any C# model class and send out property changed events without knowing what properties the model class has until runtime?
I just discovered the DLR and the DynamicObject which seems to be perfect, but due to Apple restrictions, it will not work on Xamarin.iOS.
Without teasing DynamicObject into life on iOS, the main approaches that think of are:
You could change your webservice generation code so that it produces INotifyPropertyChanged - I've used libraries that do this - e.g. http://stacky.codeplex.com/SourceControl/latest#trunk/source/Stacky/Entities/Answer.cs - and if you can't change the webservice code generation itself, you might still be able to wrap or pervert the generated code using some kind of t4 or other templating trick.
You could investigate some kind of code that maps the web service objects to some kind of observable collection (Kiliman has suggested this in comments)
You could look at some kind of valueconverter (or maybe valuecombiner) which does the binding - I can fairly easily imagine a valueconverter which takes a wrapped model object and a string parameter (the property name) and which uses those two together (with some reflection) to work out what to do. I'm not as sure how this one would work with nested model objects... but even that could be possible...
You could look at some kind of custom binding extension for MvvmCross. This isn't as scary as it sounds, but does require some reflection trickery - to understand what might be involved take a look at the FieldBinding plugin - https://github.com/MvvmCross/MvvmCross-Plugins/tree/master/FieldBinding
During the actual data-binding process, the plugin will be called via IMvxSourceBindingFactoryExtension - that would be your opportunity to hook into some other custom change event (rather than INotifyPropertyChanged). It might take a little experimentation to get this right... especially if you have nested objects (which then require "chaining" within the binding)... but I think it should be possible to produce something this way.
I am not sure if what I finalized on supports all possible functionality, but so far, it seems to satisfy everything that I need.
I really liked the idea of writing my own IMvxSourceBindingFactoryExtension. However, in investigating how to do that, I started playing with the functionality that already exists within MvvmCross. I already knew that MvvmCross would honor an ObservableCollection. What I didn't know was that I could use [] in my binding expressions AND that not only would integer indexers work, but also string indexers on a Dictionary. I discovered that MvvmCross sample code already has an implementation of ObservableDictionary within its GIT repo. It turns out, that is all that I needed to solve my problem.
So my model contains static properties AND an ObservableDictionary<string,object> of dynamic properties where the key is the name of the dynamic property and the value is the value of the property.
My ViewModel wraps this model class to send out PropertyChanged notifications on the static properties. Since the Dictionary of dynamic properties is observable, MvvmCross already handles changes to members of that dictionary, including 2-way.
The final issue is how to bind to it in my binding expression. That is where the [] comes in. If my ObservableDictionary property name is called UserValues and it contains a value at key user1, then I can 2-way bind to it by using: UserValues[user1] and everything seems to work perfectly.
One issue I see is that I am now requiring my dynamic data source to return an ObservableDictionary to me instead of just a Dictionary. Is that asking too much?
So this seems like a fairly simple answer to a common problem: Infinite loop detected in Jackosn. If, when serializing an object tree, Jackson comes upon an object it has already serialized why doesn't it just ignore it? Is there a way to do this in Jackson, or has someone created something similar?
Why all this mucking around with JsonManagedReference/JsonBackReference, which is completely insufficent if you start serializing child objects (which need a reference to the parent) some of the time and you are serializing parent objects some of the time (which obviously doesn't want the child to refer back to itself)?
It seems like now I have to create custom views that take into account every type of circular reference and use case possible which in any non-trivial ORM is a huge task.
EDIT (October 2012)
Jackson 2.x actual now DOES support identity information handling with #JsonIdentityInfo annotation! So the original answer is bit out of date...
OBSOLETE
Jackson does not support handling of object identity: this is a non-trivial task not so because of identifying shared objects which can be done by traversing object graph (incurring some overhead), but rather in figuring out how to include identity information; which ids to use and how. This in turn is somewhat similar to inclusion of type information, but now adds second dimension of extra wrapping to handle.
Doing this has been requested before, and some thought has gone into figuring out how to do it, but ratio of effort to benefit (i.e. number of requests, how badly it is needed) has been higher than adding other features.
So your best bet is to use wrapper objects and implement this manually, or have a look at XStream which can solve this (when enabled; it adds significant overhead in time) and also has JSON output mode using Jettison.
Implementing this manually for your use case is bit easier than solving the general case: you could start with BeanSerializerModifier to add wrapper handler that can keep track of object identities, and know what to serialize instead as object id.
While playing around with the Entity Framework and NHibernate using POCO entities, I made the following observation which I find a bit unusual:
I have two POCO entities, an 'Order' and a 'Product'. There is a many-to-many relationship between the two. When I add a product to an Order, I use a 'FixUp' method to ensure that the opposing side of the relationship is also updated i.e. - that the products collection of 'Orders' is also updated.
My Order POCO entity has the following method to do the 'FixUp':
private void FixupProducts(object sender, NotifyCollectionChangedEventArgs e)
{
if(e.NewItems != null)
{
foreach(Product p in e.NewItems)
{
p.Order.Add(this);
}
}
}
While profiling this scenario with EFProf and NHProf, I observed that the Entity Framework generates one more SQL statement than NHibernate, the cause of which seems to be this line:
p.Order.Add(this);
With Entity Framework, the above line causes a select to be executed on the database to return all the orders for the product 'p'. I don't expect this to happen, since I'm using lazy loading and don't actually want to access the products 'Order' collection. I just want to add an order to it.
With NHibernate no attempt is made to load the products collection of orders unless I explicitly try to access it. For example, if I say:
foreach(Order o in product.Orders)
{
Console.WriteLine(o.Id);
}
So ultimately my question is, why does Entity Framework generate the extra SQL statement? Is there a difference in the implementation of lazy loading for the two frameworks that I'm not aware of?
***EDIT TO ORIGINAL
It seems that Entity Framework doesn't behave in a lazy fashion once a method of any kind is called on the collection. Any attempt to add or count (or presumably any other operation on the collection) results in that collection being loaded into memory.
What's interesting is my NHibernate mapping (which is a bag of 'Products - shown below), appears to behave in an 'extra-lazy' fashion, even though my mapping is configured as just being lazy:
<bag name="Products" cascade ="all" table="OrderProduct" mutable="true" lazy="true">
I can 'Add' to the collection without it being loaded into memory. I think that calling 'Count' will result in the orders being loaded unless I configure it as being 'extra-lazy'.
Can anyone comment on whether this is correct?
That is how EF POCO template and its FixUp methods behave. The only ways to avoid this are:
Removing FixUp methods from POCO template
Turn off lazy loading temporarily when assigning Product to Order
It is based on the way how lazy loading is implemented. Every access to property / collection itself triggers lazy loading despite of the operation you want to use on the collection. You will have to avoid build in lazy loading completely to fully avoid it. Here is example how to achieve it for Count method - you can think about similar approach for other methods.
I think that calling 'Count' will result in the orders being loaded
unless I configure it as being 'extra-lazy'.
This is correct, calling Count as well as Contains will be optimized and will not load the whole collection in NHibernate. You may also find this EF vs NHibernate comparison interesting:
Collection with lazy=”extra” – Lazy extra means that NHibernate adapts
to the operations that you might run on top of your collections. That
means that blog.Posts.Count will not force a load of the entire
collection, but rather would create a “select count(*) from Posts
where BlogId = 1” statement, and that blog.Posts.Contains() will
likewise result in a single query rather than paying the price of
loading the entire collection to memory.
Adding a new item to an uninitialized lazy collection will not load the collection. It does not have to be mapped as extra lazy for this. Take a look at this article:
Now, on collections mapped as lazy-loading, Add() operations are
allowed even if the collection is not initialized (i.e. the collection
just acts as a proxy). When adding an object to a collection in this
state, a QueueAdd() method is called that stores the added object in a
secondary collection. Once a lazy initialization is performed, this
secondary collection is merged into the main one (I believe it’s the
DelayedAddAll() method that does this). This can be hard to debug
because lazy load is transparently triggered if you just touch the
collection with the debugger (providing the session is connected at
that moment), and everything gets initialized properly.
For example, I have window (non-document model) - it has a controller associated with it. Within this window, I have a list and an add button. Clicking the add button brings up another "detail" window / dialog (with an associated controller) that allows the user to enter the detail information, click ok, and then have the item propagated back to the original window's list. Obviously, I would have an underlying model object that holds a collection of these entities (let's call the singular entity an Entity for reference).
Conceivably, I have just one main window, so I would likely have only one collection of entities. I could stash it in the main window's controller – but then how do I pass it to the detail window? I mean, I probably don't want to be passing this collection around - difficult to read / maintain / multithread. I could pass a reference to the parent controller and use it to access the collection, but that seems to smell as well. I could stash it in the appDelegate and then access it as a "global" variable via [[NSApplication sharedApplication] delegate] - that seems a little excessive, considering an app delegate doesn't really have anything to do with the model. Another global variable style could be an option - I could make the Entity class have a singleton factory for the collection and class methods to access the collection. This seems like a bigger abuse than the appDelegate - especially considering the Entity object and the collection of said entities are two separate concerns. I could create an EntityCollection class that has a singleton factory method and then object methods for interaction with the collection (or split into a true factory class and collection class for a little bit more OO goodness and easy replacement for test objects). If I was using the NSDocument model, I guess I could stash it there, but that's not much different than stashing it in the application delegate (although the NSDocument itself does seemingly represent the model in some fashion).
I've spent quite a bit of time lately on the server side, so I haven't had to deal with the client-side much, and when I have, I just brute forced a solution. In the end, there are a billion ways to skin this cat, and it just seems like none of them are terribly clean or pretty. What is the generally accepted Cocoa programmer's way of doing this? Or, better yet, what is the optimum way to do this?
I think your conceptual problem is that you're thinking of the interface as the core of the application and the data model as something you have to find a place to cram somewhere.
This is backwards. The data model is the core of the program and everything else is grafted onto the data model. The model should encapsulate all the logical operations that can be performed on the data. An interface, GUI or otherwise, merely sends messages to the data model requesting certain actions.
Starting with this concept, it's easy to see that having the data model universally accessible is not sloppy design. Since the model contains all the logic for altering the data, you can have an arbitrarily large number of interfaces accessing it without the data becoming muddled or code complicated because the model changes the data only according to its own internal rules.
The best way to accomplish universal access is to create a singleton producing class and then put the header for the class in the application prefix headers. That way, any object in the app can access the data model.
Edit01:
Let me clarify the important difference between a naked global variable and a globally accessible class encapsulated data model.
Historically, we viewed global variables as bad design because they were just raw variables. Any part of the code could alter them at will. This nakedness led to obvious problems has you had to continuously guard against some stray fragment of code altering the global and then bringing the app down.
However, in a class based global, the global variable is encapsulated and protected by the logic implemented by the encapsulating class. This encapsulation means that while any stray fragment of code may attempt to alter the global variable inside the class, it can only do so if the encapsulating class permits the alteration. The automatic validation reduces the complexity of the code because all the validation logic resides in one single class instead of being spread out all over the app in any random place that data might be manipulated.
Instead of creating a weak point as in the case of a naked global variable, you create strong and universal validation and management of the data. If you find a problem with the data management, you only have to fix it in one place. Once you have a properly configured data model, the rest of the app becomes ridiculously easy to write.
My initial reaction would be to use a "modal delegate," a lot like NSAlerts do. You'd create your detail window by passing a reference to a delegate, which the detail window would message when it is done creating the object. The delegate—which would probably be the controller for the main window—could then handle the "done editing" message and add the object to the collection. I'd tend to not want to pass the collection around directly.
I support the EntityCollection class. If you have a list of objects, that list should be managed outside a specific controller, in my opinion.
I use the singleton method where the class itself manages it's own collections, setup and teardown. I find this separates the database/storage functionality from the controllers and keeps things clean. It's nice and easy to just call [Object objects] and have it return a reference to my list of objects.
I have been developing a web application in Seaside+Squeak recently, and have found it to be a wonderful experience. Seaside really is head and shoulders above every other framework out there, and I feel as though I am working at a higher level of abstraction (above the HTTP request/response cycle and HTML templating that other frameworks make you deal with).
That said, I'm a little confused about Seaside components. I recently had to display a list of objects on a component (similar to the stackoverflow front page). At first I made each object a component (a subclass of WAComponent), but this proved to be really wasteful, and I had to set #children dynamically in the parent component for it to work at all. I then tried making them render objects (objects that aren't subclasses of WAComponent, and render using renderOn: instead of renderContentOn:, like components do). This worked, but now they could no longer access global state in the session object as components can (using #session). Then I discovered "WACurrentSession value", which gives any object access to the current Seaside session object. I was now able to make them render objects. In addition, I discovered that I could rewrite a lot of my other, more minor components as render objects, too.
Besides needing call/answer or backtracking state, what other reasons are there for using components over render objects?
This is a frequent point of confusion for new Seaside users. We have tried hard to make this clearer in Seaside 2.9, which is currently in Alpha, but I will try to focus on 2.8 here since it sounds like that is what you are using.
First of all, you are correct that you do not need to use a Component in order to access the Session. Seaside 2.9 moves #session up to a new class WAObject which makes it accessible to almost all Seaside objects (including Components) but you can definitely refer to WACurrentSession yourself for now in 2.8.
Components provide roughly the following functionality in 2.8:
#renderContentOn: is called with an instance of whatever renderer class you specify in #rendererClass (instead of whatever renderer is in use when your object is asked to render itself)
A hook (#updateUrl:) to allow updating the URL used by the renderer to generate links
Hooks (#updateRoot:, #style, #script) to allow updating the HEAD section of the HTML document
The ability to be the root of an Application
Hooks (#updateStates:, #states) to make state backtracking easier
A hook (#initialRequest:) to allow initialization based on the request that caused the Session to be created
A facility (#children) to make sure all components below you will also have the above hooks called on them
The ability to add Decorations
The ability to show/answer/call (uses Decorations)
Some convenience methods (#inform:, #isolate:, etc)
If you don't need any of the above, you don't need a Component. If you need any of the above, you pretty much do need a Component unless you want to implement the equivalent functionality on your own class.
The simplest metric is probably: if you intend to keep the object around between HTTP requests it should be a Component; if you intend to throw the object away and create it on each rendering pass it probably doesn't need to be. If you imagine an application that was displaying blog pages, you'd probably have Components for a menu, a blog roll, the blog body, each comment, and so on. You might want to factor out the reading of the blog's markup and generation of its HTML so that you could support different markups or different renderers and so that the comment Components could support the same markup. This could be done with a non-Component class that implements #renderOn: and could be created and used by other Components as needed.
Seaside 2.9 currently splits up the above functionality by making WAPresenter concrete and introducing WAPainter as its superclass. 1-3 above are implemented on WAPainter and 4-7 on WAPresenter so you have your choice of what to subclass depending on your needs. It also removes a lot of methods from WAPresenter and WAComponent in an effort to make them easier for end users to understand.
Hope that helps.