One view with many presenters?

Topics: CAB & Smart Client Software Factory
Sep 22, 2006 at 10:59 AM
originally posted by: sqvarius

I need to implement different behaviors for one view.
Should I use one presenter for particular scenarios ?

How can I inject different presenter for each workitem?

public class View
{
...
private IViewPresenter myPresenter;

Dependency - ?????
public IViewPresenter MyPresenter
{
set{ myPresenter = value;}
}
...

}

or should I use one presenter which works with many workitems?
Sep 22, 2006 at 12:08 PM
originally posted by: PauloMorgado

Have you tried generics?

I'm using something like this:

public class Presenter<TView>
{
InjectionConstructor
public Presenter(Dependency WorkItem workItem)
{
workItem.SmartParts.AddNew<TView>();
}
}

This way I can have different views for the same presenter and different presenters for the same view.
Sep 22, 2006 at 11:30 PM
originally posted by: sqvarius

Thanks, I don't know that I can inject WorkItem to Presenter.
I' ve found this:
http://www.gotdotnet.com/codegallery/messageboard/thread.aspx?id=22f72167-af95-44ce-a6ca-f2eafbf2653c&mbid=c09776ca-f94c-4c83-a80c-75d381cabdd6&threadid=961ba9d7-356b-4cd1-8bac-6f0946c157c8

but it doesn't work for me.

I add presenter to workitem .

workItem.AddNew<Presenter>();
workItem.AddNew<MyView>("view");

and try to inject controller to view

public class MyView: UserControl
{

private IPresenter presenter;

Dependency
public IPresenter Presenter
{
set{ presenter = value;}
}


}

but exception is thrown: "Can not create an instance of type Test.IPresenter'. "Cannot create abstract class."
Sep 23, 2006 at 7:38 AM
originally posted by: JKraft4PIT

First off, Have you ever used interfaces?

Second if so you have forgotten how, you have to implement the interface in a different class and then create that class. (this is object programming 101).

Third, You may want to look into Generics, they are new to 2.0 and are great!!

Also I was looking ove the post you linked and found this line:
"This works well, but obviously, I still have to declare the implementing class within the view component, which is not what I was up for."

That is what i am talking about.
Sep 23, 2006 at 7:55 AM
originally posted by: ChrisHolmes

"I need to implement different behaviors for one view. "

Sounds like a job for an abstract base presenter class to me.

The alternative is to extract the particular behavior to a separate class outside of the presenter (maybe a manager class of some kind). Then implement a factory pattern to create the specific instance of the manager you require for a given scenario. Inject the concrete factory into the presenter and allow it to do the work.
Sep 24, 2006 at 12:17 AM
originally posted by: sqvarius

I know interfaces and generics, but my english is not so good :)

Have you read this sentence in the post I linked?

"Now, you can still use an interface to a Controller without your View having to know about any specific concrete type. To do that means you have to create the Controller first, in the WorkItem, and add it to the Item collection. Then when you create the View, if you have decorated your IMyController with a basic Dependency attribute (non-creational) then it will fetch the pre-existing Controller from the WorkItem and use it."

It doesn't work. Have you tried this solution ?

I've found this in CAB documentation:

"ObjectBuilder encapsulates features that simplify the creation of object instances. It can:
Ensure the creation of specific concrete class instances, even when requests are for abstract types."

Have I missed anything?
Sep 25, 2006 at 4:48 AM
originally posted by: sqvarius

Ok. This is my solution.

WorkItem code:

protected override void OnRunStarted()
{
base.OnRunStarted();

TypeMappingPolicy policy = new TypeMappingPolicy(typeof(UserControl1Presenter), "p1");
InnerBuilder.Policies.Set<ITypeMappingPolicy>(policy, typeof(IUserControl1Presenter), "p1");

ZoneSmartPartInfo info1 = new ZoneSmartPartInfo("Bottom");
info1.Dock = System.Windows.Forms.DockStyle.Right;
ZoneWorkspace workspace = (ZoneWorkspace)this.Workspaces"zoneWorkspace1";
UserControl1 view = this.Items.AddNew<UserControl1>("view2");
workspace.Show(view, info1);

}

View code:

IUserControl1Presenter presenter;
Dependency(Name="p1")
public IUserControl1Presenter Presenter
{
set { presenter = value; }
}

Changing builder TypeMapingPolicy I can change type of presenter exposed on my view.