tag:robotlegs.tenderapp.com,2009-10-18:/discussions/problems/142-issue-subclassing-a-mediatorRobotlegs: Discussion 2018-10-18T16:35:15Ztag:robotlegs.tenderapp.com,2009-10-18:Comment/24952932010-08-06T16:48:17Z2010-08-06T16:48:17ZIssue subclassing a Mediator<div><p>Hi,</p>
<p>i'm currently building an app that uses the composite pattern. For this reason i have a BaseView Class that's the base class for every view within the pattern. So i decided to create a BaseViewMediator to manage the shared functionality of each view, with the idea being to then subclass this Mediator for any view that needed additional management.</p>
<p>This all worked fine, until i attempted to subclass the BaseViewMediator. So i have,</p>
<p>LoginView extends BaseView</p>
<p>and</p>
<p>LoginViewMediator extends BaseViewMediator</p>
<p>Then in a Command i have</p>
<p>mediatorMap.mapView( BaseView, BaseViewMediator );<br />
mediatorMap.mapView( LoginView, LoginViewMediator );</p>
<p>The BaseViewMediator Class has a public var that's marked for injection called 'view'</p>
<p>[Inject]
public var view : BaseView;</p>
<p>But when LoginView gets added to the stage and the LoginViewMediator is created, i get this error,</p>
<p>Error: Injector is missing a rule to handle injection into target [object LoginViewMediator]. Target dependency: com.myApp.view.pages::BaseView</p>
<p>I'm presuming that when a view is injected into a Mediator, the injection is being handled automatically, i.e even though the view Class mapped to the Mediator hasn't been mapped for injection explicitly, the injector knows to assign the instance of the class associated with the Mediator. However, i'm a bit stumped, as i'd presumed that as LoginView is a subclass of BaseView, it wouldn't have any issue assigning it to 'view'?</p>
<p>I hope this all makes sense, any help would be appreciated.</p>
<p>Cheers,</p>
<p>James</p></div>jamesrtag:robotlegs.tenderapp.com,2009-10-18:Comment/24952932010-08-10T15:41:00Z2010-08-10T15:41:00ZIssue subclassing a Mediator<div><p>Hi James,</p>
<p>Unfortunately there are some limitations with the current implementation of the Mediator Map. When the mediator is mapped we store a config object that keeps track of the "type" of view to be injected:</p>
<p><a href="http://github.com/robotlegs/robotlegs-framework/blob/v1.1.2/src/org/robotlegs/base/MediatorMap.as#L108">http://github.com/robotlegs/robotlegs-framework/blob/v1.1.2/src/org...</a></p>
<p>Later, when the mediator is created, we use that information to do a temporary mapping for the view component:</p>
<p><a href="http://github.com/robotlegs/robotlegs-framework/blob/v1.1.2/src/org/robotlegs/base/MediatorMap.as#L145">http://github.com/robotlegs/robotlegs-framework/blob/v1.1.2/src/org...</a></p>
<p>As you've discovered, this means that you can't specify two view injection points in the same mediator (one of them won't have been mapped and the DI container will throw an error).</p>
<p>A work-around is to specify the <code>injectViewAs</code> parameter as the BaseView type for all the mappings and then use a getter to up-cast the injected property in your derived mediators. Something like this:</p>
<pre>
mediatorMap.mapView( BaseView, BaseViewMediator );
mediatorMap.mapView( LoginView, LoginViewMediator, BaseView );
</pre>
<p>And then in LoginViewMediator:</p>
<pre>
[Inject] public var view:BaseView;
public function get loginView():LoginView
{
return view as LoginView;
}
</pre>
<p>Hope that helps!</p></div>Shaun Smithtag:robotlegs.tenderapp.com,2009-10-18:Comment/24952932010-08-13T13:36:43Z2010-08-13T13:36:43ZIssue subclassing a Mediator<div><p>why are you adding stuff to the mediatorMap in a command and not the context?</p></div>Nikos tag:robotlegs.tenderapp.com,2009-10-18:Comment/24952932010-08-13T14:01:05Z2010-08-13T14:01:05ZIssue subclassing a Mediator<div><p>With complex projects (one's where there is a LOT of configuration) it is common to break configuration up into multiple Commands (e.g. MapControllersCommand, MapModelsCommand, MapServicesCommand, MapViewsCommand) and bind these commands to a STARTUP event. It's usually only with small projects that one would configure all rules directly in the context in the startup() hook.</p></div>Shaun Smithtag:robotlegs.tenderapp.com,2009-10-18:Comment/24952932010-08-13T14:10:52Z2010-08-13T14:10:53ZIssue subclassing a Mediator<div><p>Thanks for the help Shaun. I ended up casting the viewComponent in the baseViewMediatior to BaseView</p>
<p>protected function get baseView():BaseView<br />
{</p>
<pre><code>return BaseView( viewComponent );</code></pre>
<p>}</p>
<p>and then used Inject to inject the actual view class into the subclass of BaseViewMediator.</p></div>jamesrtag:robotlegs.tenderapp.com,2009-10-18:Comment/24952932010-08-13T14:24:30Z2010-08-13T14:24:30ZIssue subclassing a Mediator<div><p>Yup, that's another way to do it. In a future version we should be able to handle this more elegantly :)</p></div>Shaun Smithtag:robotlegs.tenderapp.com,2009-10-18:Comment/24952932010-08-13T14:31:55Z2010-08-13T14:31:55ZIssue subclassing a Mediator<div><p>sheesh thats ugly :)<br />
</p></div>Nikos