using INotifier at a late point

Topics: Writing themes
Mar 15, 2011 at 12:53 PM

I have a condition where I should trigger a message from within Layout.cshtml (indirectly by creating a shape which has a shapebuilder-oncreated-event which uses some service to add model data - and the service uses INotifier).

But at this point the NotifyFilter class already has pulled all messages and so all successive calls of INotifier.Add() are going into Nirvana.

I was able to create a quick workaround as follows but I wonder if the Orchard framework should handle this loss of information in a smarter way -- or at least introduce a state property which signals that INotifier.Add() is clueless because INotifer.List() was already called and handled.

public static void PushLateMessage(this WebViewPage<dynamic> page, NotifyType notifyType, LocalizedString message)
	PushLateMessage(page.WorkContext, page.ShapeFactory, notifyType, message);

public static void PushLateMessage(this IOrchardServices services, NotifyType notifyType, LocalizedString message)
	IShapeFactory shapeFactory = services.New;
	PushLateMessage(services.WorkContext, shapeFactory, notifyType, message);

public static void PushLateMessage(this WorkContext context, IShapeFactory shapeFactory, NotifyType notifyType, LocalizedString message)
	dynamic shapeBuilder = shapeFactory;
	var entry = new NotifyEntry { Type = notifyType, Message = message };

Mar 15, 2011 at 10:48 PM

Why do you need to do it that late? Shapes should not be executing complex logic, they should do dumb rendering of dumb data (let's not reproduce WebControls).

Mar 18, 2011 at 11:50 PM

The shape itself is just dumb rendering of dumb data. But the IShapeTableProvider implementation is adding relevant data to the shapes model by the use of a service.

The main problem (I think) is that it's inside Layout.cshtml where I'm creating this shape very late and inject it into a zone (just like BadgeOfHonor and Branding are handled) -- I only inject it when the zone is empty, so maybe there exists some other place (=time) where I could check this before INotifier injects its shapes? If I handle it via IResultFilter (like NotifyFilter does) how can I ensure that NotifyFilter never gets called before my IResultFilter implementation gets called?

Mar 19, 2011 at 12:08 AM

It would really help if you could explain what exactly you are trying to do here. You said initially that you wanted to trigger a message from layout. That doesn't sound like a good idea: layout should not have code that does anything else than dumb rendering of dumb data. You have got to know about that stuff earlier.

Mar 19, 2011 at 12:56 AM

For my current "problem" it's not critical if there is a notification message at all -- my question was mostly how to globally catch situations where the INotifier-List already has been processed and some module/event/handler/filter tries to insert some more just a moment too late; especially when I would do some critical work in a IResultFilter as noted above.

I know I would have to refactor my "problem" in some way that the automatic creation of a new Layer (which triggers the message about that task) takes place at a different place, maybe be just introducing a controller action which does this and immediately redirects to the widget editor.

Mar 19, 2011 at 1:02 AM

Yes, if it happens too late I would encourage refactoring so it happens earlier. All that should remain to do when rendering is rendering of dumb data. I can't stress that point enough. :)

Mar 19, 2011 at 1:11 AM

Ok :)  but I'm still curious if I could control the order of many IResultFilter implementations since looking at NotityFilter at seems to be ok doing complicated things there -- but using INotifier.Add() there could work randomly.

Mar 19, 2011 at 3:15 AM

Not following you.

Mar 19, 2011 at 2:40 PM

If I have 2 (or more) filter classes (implementing IResultFilter) in 2 (or more) modules then the call order of the filter methods could be random. If my filter is called before NotifyFilter then I'll see my notifications created there -- otherwise not.

Mar 19, 2011 at 10:31 PM

What are the filters notifying about?