Effectus: Building UI based on conventions

I waited for a while after my article was posted, to see if anyone caught on to some of the things that I did in the sample code that weren’t related to NHibernate usage. It seems that no one caught on to that, so I’ll try pointing them out explicitly.

The basic format of a feature in Effectus is this:

image

Each feature have a Presenter (business logic for the feature), a View Model, which is directly bound to the View and is the main way that Presenter has to communicate with the View. The main responsibility of the Model is to be bound to the UI, and allow the presenter to update it, but it is not quite enough.

The UI also need to raise events and handle user input. A common example is handling button clicks. You can’t really map them into Model behavior, at least not easily and in a way that make sense to the developers. Instead, I defined a set of conventions. As you can see in the picture, based on the name of the element, we match is with the appropriate execute method and the way to decide if the command can execute. Under the cover, we generate the appropriate ICommand instance, bound to the Presenter behavior.

image

If you look at the code, you can see that the conventions extend even to handling the selected item changed in a list box, including passing the newly selected instance back to the presenter. Those conventions are project specific, based on what the project need, and they result in a code base that is very easy to read and follow. Moreover, they result in a codebase that is relatively free from infrastructure concerns.

I am going to have a few more posts about Effectus, can you figure out what else I put in that code base?

Print | posted on Saturday, December 19, 2009 12:00 PM

Feedback


Gravatar

# re: Effectus: Building UI based on conventions 12/19/2009 1:09 PM Omer Mor

A little thing called "love" ?
seriously I have no idea, but I'm sure the following comments will unveil it :-)


Gravatar

# re: Effectus: Building UI based on conventions 12/19/2009 1:12 PM Ayende Rahien

Omer,
Read the code, and look at the future posts :-)


Gravatar

# re: Effectus: Building UI based on conventions 12/19/2009 1:52 PM firefly

What is a "Fact"? What design pattern does that follow?


Gravatar

# re: Effectus: Building UI based on conventions 12/19/2009 1:55 PM Ayende Rahien

Read the code, and wait for the post to show up


Gravatar

# re: Effectus: Building UI based on conventions 12/19/2009 1:55 PM firefly

Also the sql script throw some error in SQL Management studio.

INSERT INTO [ToDo].[dbo].[ToDoActions]
([Version],
[Title],
[Content],
[Status],
[CreatedAt],
[CompleteBy])
VALUES (1,
'Write App',
'Should really write the application',
1,
Getdate(),
Getdate() + 3,) <--- the extra comma in all the insert cause the error. Remove this will fix it.


Gravatar

# re: Effectus: Building UI based on conventions 12/19/2009 2:08 PM alwin

@firefly

ayende.com/.../conditions-and-facts.aspx


Gravatar

# re: Effectus: Building UI based on conventions 12/19/2009 2:09 PM Mihai Lazar

I don't know why you thought nobody noticed what you put in the code. The command publishing I was looking for was found in your code ;)


Gravatar

# re: Effectus: Building UI based on conventions 12/19/2009 2:16 PM Ayende Rahien

Mihai,
I didn't get any response about that


Gravatar

# re: Effectus: Building UI based on conventions 12/19/2009 2:23 PM firefly

Thanks alwin, fact is a pretty generic word... so it's kinda hard to search for it :)


Gravatar

# re: Effectus: Building UI based on conventions 12/19/2009 5:49 PM Dennis

Reinventing CSLA?


Gravatar

# re: Effectus: Building UI based on conventions 12/19/2009 6:07 PM Eugene

A possibly offtopic question regarding facts. I post it here since unfortunately the comments for the post linked by alwin are closed.

public Fact(INotifyPropertyChanged observable, Func predicate) ...

Why do you require an observable if you could decompile the predicate, hunt for INPCs mentioned there and listen to those? That would work as intended for a good 90-95% of all cases.

In the cases when a simple heuristics works for us (i.e. it detects all INPCs we need and doesn't detect INPCs that are irrelevant) we can get rid of Facts at all, e.g. change the original sample:

public Fact CanMovePrev { get { return new Fact(CurrentPage, () => CurrentPage > 0); } }

to a much more readable analogue:

public bool CanMovePrev { get { return CurrentPage > 0 } }


Gravatar

# re: Effectus: Building UI based on conventions 12/19/2009 6:13 PM Daniel AUger

Ayende - When I read the article the thought did cross my mind that the non-nhibernate aspects of Effectus were extremely interesting. Most "sample applications" have a throwaway / bland architecture and infrastructure. The Effectus architecture and infrastructure really grabbed my attention. I'm very happy you are going to elaborate on these aspects via your blog.


Gravatar

# re: Effectus: Building UI based on conventions 12/19/2009 6:16 PM Eugene

Also wanted to add that the word "decompile" I used doesn't meant fully-fledged decompilation like the ones Reflector does.

Imo we can be fine with just checking all ldflds and calls to property getters - whether they return INPCs. To do that one needs to find a way to convert byte[] method bodies returned by reflection to a stream of ops. For that purpose one can use Cecil, CCI or something hand-made. E.g. for a similar purpose I've developed my own IL reader: xenogears.googlecode.com/.../Parse/


Gravatar

# re: Effectus: Building UI based on conventions 12/19/2009 6:44 PM David Perfors

Ayende - The thing that I found weird was that you decoupled the features so much that you use the name of the namespace (or part of it) as a string to fire up the presenter. It is not something I would do (since I don't like strings in code..), I am looking forward to the post about this...
The way you use for wire the events is very nice :)


Gravatar

# re: Effectus: Building UI based on conventions 12/19/2009 6:59 PM ivos

Pretty interesting, actually. I used to work with MVP for my web applications and I don't reallt like MVVM (It's not bad, but I don't like it).

Features that I would like to see how it's implemented:
- Validation: I would like to have the validation in the model side.
- Transaction management: maybe an aspect in the On.... methods?
- Tell the view to hide/show controls (change the visual state): The properties would be bound to presenter properties?

I didn't downloaded the code, just navigated it a little, so maybe there's something already defined that I missed.


Gravatar

# re: Effectus: Building UI based on conventions 12/19/2009 7:02 PM Ayende Rahien

Eugene,
Because that would be:
a) a lot of hard work
b) trigger the too much magic part
c) would invalidate scenarios such as composite observables


Gravatar

# re: Effectus: Building UI based on conventions 12/19/2009 7:26 PM Eugene

Ayende,
a) and c) need to be done only once, and then can be used across all projects that use facts - tho surely do as it feels good for you to do.

What really got me interested is b). How do you detect the "too much magic"? For me things that don't leak their internals are always ok, regardless of their complexity, given that they do simplify routine tasks. What's your opinion on this?


Gravatar

# re: Effectus: Building UI based on conventions 12/19/2009 8:31 PM Mark Nijhof

I really like Conventional based stuff a lot. Something that I did in my CQRS example application is using Win Forms and MVP where I conventionally hook-up the view events with presenter event handlers. It is using reflection which doesn't get cached but honestly on a window start this isn't really a big concern. And if there is an event that doesn't get handled I throw an exception.

The base presenter can be found here: github.com/.../IPresenter.cs

-Mark


Gravatar

# re: Effectus: Building UI based on conventions 12/19/2009 8:47 PM Alexandre Trigueros

My first post here to send you a big thank you !
I didn't have much opportunities to use WPF.
Your sample is a gold mine.
Even if i'm not really fond of the autowiring event based on name convention.

And also, why did you do an Observable class instead of using the databindingFactory to generate INotifyPropertyChanged objects ?

Anyway, thanks again for the sample.


Gravatar

# re: Effectus: Building UI based on conventions 12/19/2009 10:13 PM Mikael Syska

Great stuff, always enjoy reading your posts.


Gravatar

# re: Effectus: Building UI based on conventions 12/20/2009 1:04 AM c.sokun

Love to see DataBindingFactory extend to support 1-1, 1-M & M-M oh would that require programmer to deal with it themself? Would be cool is I could have the same experience as [ARDataBind] in MR gave :)


Gravatar

# re: Effectus: Building UI based on conventions 12/20/2009 12:32 PM Ayende Rahien

Eugene,
a & c may be only needed once, but that is still complex, and I don't see any huge benefit that it gives in return.
As for too much magic, that is simple formula, how much time are you going to spend debugging a particular problem?


Gravatar

# re: Effectus: Building UI based on conventions 12/20/2009 12:34 PM Ayende Rahien

Alexandre,
data binding factory is for entities, not for the type of stuff that I used Obserable for. It is simpler to write the INPC for that


Gravatar

# re: Effectus: Building UI based on conventions 12/20/2009 12:34 PM Ayende Rahien

Sokun,
You have the code, write the extension


Gravatar

# re: Effectus: Building UI based on conventions 12/20/2009 12:58 PM Eugene

Ayende,
Thank you.


Gravatar

# re: Effectus: Building UI based on conventions 12/20/2009 5:24 PM Josh

This is how Caliburn does it, I assume it was your contribution?


Gravatar

# re: Effectus: Building UI based on conventions 12/20/2009 6:47 PM firefly

After some digging I must say that I really like the code base. I love convention over configuration. With some minor refactoring I was able to incorporate most of it into my code base. Very neat :)

This come just in time as I am working on my first WPF application and I started to get a little sick of the wiring.


Gravatar

# re: Effectus: Building UI based on conventions 12/20/2009 7:12 PM FallenGameR

Nice architecture =) I wonder if I need MS Prism Commands now.
Ayende, how do you think - will it be easy to add validation to model properties?


Gravatar

# re: Effectus: Building UI based on conventions 12/21/2009 2:15 AM firefly

So is this stuff going to end up in Caliburn v2? :) Somehow I get the feeling that it will be.

It's actually cleaner than the way Caliburn is doing it currently. It's cleaner for two reason. First Caliburn put the INotifyPropertyChanged on the Model, this put it directly on the property.

Putting it on directly the model require that the user have to raise seperate notification. For example

# public string LastName
# {
# get { return _lastName; }
# set
# {
# _lastName = value;
# NotifyOfPropertyChange("LastName");
# NotifyOfPropertyChange("CanSave");
# }
# }

I think that is a little ugly. If there is more commands that tied to LastName the situation get hairy real fast...


Gravatar

# re: Effectus: Building UI based on conventions 12/22/2009 2:15 AM P

Slightly off the topic of this post, but the naming convention in the per-scenario is something I struggle with :)

Doesnt this kill the "Go to type" (Ctrl + N for resharper bindings) feature in resharper? For a large code base, this is a must IMO.

I completely agree with a folder (namespace) per scenario, but I typically add the scenario name to Presenter/ViewModel/View just to support resharper navigation. Its redundant, but I would buy a resharper license just for the said feature alone.


Gravatar

# re: Effectus: Building UI based on conventions 12/22/2009 2:33 AM P

Oh and...

[Quote]Each feature have a Presenter (business logic for the feature), a View Model, which is directly bound to the View and is the main way that Presenter has to communicate with the View. The main responsibility of the Model is to be bound to the UI, and allow the presenter to update it, but it is not quite enough.[/Quote]

I cannot agree more. MVVM forces people to shove a bunch of logic into something that should be strictly for databinding. Presenter-ViewModel-View FTW!


Gravatar

# re: Effectus: Building UI based on conventions 12/22/2009 3:07 AM firefly

Resharper should work fine, each in it own namespace.


Gravatar

# re: Effectus: Building UI based on conventions 12/22/2009 9:08 AM Ayende Rahien

Josh,
Nope, that was parallel evolution


Gravatar

# re: Effectus: Building UI based on conventions 12/22/2009 9:09 AM Ayende Rahien

FallenGameR,
It should be very easy, sure. Either directly in the property set or as an extra layer that will handle this in the DataBindingFactory.
It may take a bit of infrastructure on the UI side to handle validation errors correctly, but that wouldn't be too hard.


Gravatar

# re: Effectus: Building UI based on conventions 12/22/2009 9:11 AM Ayende Rahien

P,
Yes, it would. The naming isn't mandatory, and I am not too attached to it.


Gravatar

# re: Effectus: Building UI based on conventions 12/22/2009 5:16 PM Christopher Bennage

@firefly you can use this approach in Caliburn v1 RTW. It still needs to mature a bit, but it's the approach we took on our most recent project. Though we occasionally ran into areas where we had to use the old Caliburn style.


Gravatar

# re: Effectus: Building UI based on conventions 12/23/2009 12:13 AM firefly

@Christopher, thanks for clarifying that. I studied your example and I wasn't real clear of what convention to follow. Though isn't the new convention doing it right in the xaml?


Gravatar

# re: Effectus: Building UI based on conventions 12/23/2009 6:53 AM P

@firefly

Resharper will work fine calling everything presenter, but when you want to goto the "Inactive Customer Email Presenter" (for example), you can no longer jump to "ICEP" because you only called it "Presenter". You are basically back to manually navigating via solution explorer.


Gravatar

# re: Effectus: Building UI based on conventions 12/23/2009 7:12 AM firefly

@p You can type Presenter, it will list all of the presenter... along with their namespace. Not that it's optimal, just that it still work.


Gravatar

# re: Effectus: Building UI based on conventions 12/23/2009 7:15 AM firefly

@p, Oh I also want to say thanks, I didn't know about that feature until you mentioned it the other day. There is always something about Resharper to discover :). I've always used Ctrl Click to navigate


Gravatar

# re: Effectus: Building UI based on conventions 1/13/2010 5:50 PM Matt Warren

Ayende, thanks so much for this code, it's just what I needed. I converted it to work with .NET 2.0 and Winforms for a project I'm working on.


Gravatar

# re: Effectus: Building UI based on conventions 1/13/2010 5:51 PM Ayende Rahien

Happy to hear that.


Gravatar

# re: Effectus: Building UI based on conventions 1/18/2010 6:24 PM lg

Hmmm.... I'm not a pro,, so I wonder,,, translations to other languages... it is possible or will break the binding?

//lg


Gravatar

# re: Effectus: Building UI based on conventions 1/21/2010 9:45 AM Ayende Rahien

Ig,
No, it wouldn't. It just depend how you are handling the i18n

Comments have been closed on this topic.