Thursday 17 December 2009

Prism Sample: Basic Concepts

As stated in my earlier post, this model solution attempts to illustrate how Prism and Unity are used, what is a module, what belongs in one and what doesn’t, the use of interfaces and design patterns.
One of the most basic aspects of code organisation is knowing “what goes where”.  This is especially true with Prism projects.  Given you will likely have a dozen or more projects in your solution, it’s pretty important to sort out early on where things belong.
I always try to minimise dependencies between my assemblies; and from time-to-time work-out what would be required to take a module and drop it into another application.  I’m always looking for ways to remove a dependency or decouple.  Even if I don’t have an immediate requirement to do that, as a general rule it’s a good idea.

Namespaces
Picking the right naming convention for your projects and namespaces is pretty important.  I would spend ample time on this before embarking on any serious coding.  Maybe start with a prototype solution and put in some basic modules, a shell, some services, and their accompanying interfaces.  Play around with it and massage it into something you're comfortable with.  I think there is a natural order and organisation for these various projects and components.

Microsoft's recommended namespace convention is:
Company.(Product|Technology)[.Feature][.Subnamespace]

for example, if I were creating an advertising module for Blogger, I would see something like...

Blogger.Advertising.Interfaces
Blogger.Advertising.Views
Blogger.Advertising.ViewModels
Blogger.Advertising.Services
Blogger.Advertising.Services.Interfaces

Microsoft has an excellent guideline for create .Net components at: http://msdn.microsoft.com/en-us/library/ms229026.aspx

Implementation vs Interface
It's important to understand the difference between implementation and interface as it applies to modular development.  An interface is simply a public contract that defines an exposed surface.  Whereas, implementation deals with the deploy or realisation of the interface.  Interfaces do not contain business logic,  simply a definition of what something will look like once it is implemented.
Prism and Unity makes heavy use of interfaces.  Interfaces are mapped to your implementation classes, either in code or in a configuration file.

The following tips may be obvious to some, but I felt it was worth mentioning:

Tip #1 - Do not create strong references to implementation assemblies.
The exception to this are assemblies which comprise your Model.

Tip #2 - Do not place anything in your implementation assemblies which forces other assemblies to create a strong reference.
An example of this are Event classes.  You may have a module which publishes events, presumably to be subscribed to by other modules.  Do not include the Event class in your module assembly, instead place it in your module's interface assembly.  This makes it available to other assemblies though the interface reference.  Another common example are enumerations.

Tip #3 - Do not register your implementation classes in the Module Initialize method.
Registering classes in the Initialize method implies a specific implementation, but not all implementations.  Instead map your classes in a Unity configuration file.

Tip #4 - Do not inject views into regions in the Module Initialize method.
I never understood why anyone would want to do this, as it pretty much ruins any chance of reusing the module.  Instead, delegate view orchestration to another module, layer or layout manager.

In fact, I can't think of good reason to put any code in the Module Initialize method.

These tips address some hidden or covert implementation that commonly occurs in Prism development.

No comments: