Sharing a view across two project.

Topics: CAB & Smart Client Software Factory
Dec 18, 2006 at 1:03 PM
originally posted by: ovidius

Is it possible to share a view across two project?
If yes, whats the best way to create service and view.
I think to create the view in a common project and service and controller in the appropriate module but in this way i must reference all projects in the common project. In this way i can't prevent to load a specific module only to certain users.

Whats the best way?
Dec 20, 2006 at 8:23 AM
originally posted by: ChrisHolmes

Yes, it is possible to share a view across modules.

How I would do it:

I'd first create a library with view definitions (interfaces) in it. Then I'd create a library with view implementations in it (concrete views). Since the view interfaces are in a separate library, it would allow for multiple implementation libraries if you wanted different views for different customers.

I'd do the same thing with services: a separate library for the contracts (interfaces) and a separate library for implementations.

Views (in my opinion) shouldn't have access to services - unless it's a specific service that does some GUI operation. I try and keep my views as dumb as possible; there is no business logic in them. The only logic my views have is graphics related: changing colors, disabling buttons or fields, etc. The presenter/controller is where I keep the logic, and that's testable.
Dec 20, 2006 at 10:21 AM
originally posted by: ovidius

Thanks Chris,

i'll try this way.
So i must reference view library in all my project? This cause to register all the views and services in root woorkitem, also if i don't need it?
You refer to views in workitem via intefaces?
Dec 20, 2006 at 10:35 AM
originally posted by: ChrisHolmes

"So i must reference view library in all my project?"

Only on the CAB projects that need to use them. For instance, our whole project right now is somewhere around 33+ "project" files. Only three of them would reference a View library if it existed (we actually have two "views" that we share across modules, so that file is referneced by three projects). It's probably not as many references as you think.

"This cause to register all the views and services in root woorkitem,"

Oh no, we don't do it that way. We don't register anything with the RootWorkItem. We let the individual modules instantiate whatever services they require on startup and add those to the main WorkItem of a Module. This makes our project modular and lessens the coupling with the shell. It also reduces the need to load things that unloaded modules may not use.

For instance: suppose you load three services at the RootWorkItem via the Shell (Services A, B, and C). And suppose three different modules use those services (ModuleA, ModuleB, and ModuleC). But suppose a client doens't have permission to load Module C, thus they have no use for ServiceC either, but if you load it in the RootWorkItem via the Shell, it's loaded - whether they need it or not.

We treat all of our Modules as self-contained units. They know nothing of the shell or the RootWorkItem (with the exception of the UIExtensionSites, which they know of via a Service - the only one loaded at the RootWorkItem by the Shell).

"You refer to views in workitem via intefaces?"

Always. We only work with interfaces. Our presenters have a reference to the view via the interface - they know nothing of a concrete implementation. The WorkItem knows about the concrete implementation, obviously, because it creates the View and adds it to the Items collection. But the presenters themselves never know about the concrete view they are being attached to - only the interface.

Now, if a WorkItem needed to reference a view - it would also reference the interface as well. The only time a concrete view is used is at the moment of creation. Everywhere else it's the interface.
Dec 20, 2006 at 2:34 PM
originally posted by: ovidius

"You refer to views in workitem via intefaces?"
Always. We only work with interfaces. Our presenters have a reference to the view via the interface - they know nothing of a concrete implementation. The WorkItem knows about the concrete implementation, obviously, because it creates the View and adds it to the Items collection. But the presenters themselves never know about the concrete view they are being attached to - only the interface.

Now, if a WorkItem needed to reference a view - it would also reference the interface as well. The only time a concrete view is used is at the moment of creation. Everywhere else it's the interface.

---------

Did you mean to use interface like ModuleLoader project on CAB HOL?

I know this, but, forgive me i didn't understant how to use Interface.
By this way, i think one interface correspond to one presenter/controller so why i must use it?
Is it more easy to use a class that derive from controller ?
Mybe i don't undersant very well how to use interface.
Could you show me an example?
Dec 20, 2006 at 2:44 PM
originally posted by: ChrisHolmes

Interface = C# Interface. Like:

public interface IMyView
{
UpdateView(string employeeName);
}

Then a concrete implementation:

public class MyView : IMyView
{

public void UpdateView(string employeeName)
{
this.EmployeeTextBox.Text = employeeName;
}
}



That being the most simple case. There's two points to doing MPV/MVC this way. The first is that it allows you to use different concrete implementations of a View class without the Presenter/Controller needing to know about it. The Presenter/Controller just knows about the Interface (IMyView). So you could replace MyView with MyView2 if you wanted to, for a different client or user, for example.

The second thing this allows you to do is Mock your View for testing.

I'd recommend reading up on Model-View-Presenter or Model-View-Controller a bit in the .NET circles to get a better handle on this way of writing view code. You'll learn more from that than having me attempt to describe it here :)