Welcome to MSDN Blogs Sign in | Join | Help

In a previous post, I mentioned that there are difficulties with using the Visual Studio extensions for Windows SharePoint Services (VSeWSS) in combination with interfaces. It turns out that this problem is not just limited to using base classes, but also to using base classes in different assemblies.

The problem:

Just a small recap of the problem i was facing:

I had placed an interface in a different assembly than the implementation. For example, we had created an interface for doing logging, the ILogger interface and had created a basic implementation for this interface. Our own reusable code was using this ILogger, however, we wanted users of our library to be able to create and plug in their own logger. To do that, they have to derrive from the ILogger interface. However, as soon as you would do this, your project wouldn’t package anymore.

While packaging, i got the following error:

Error    1    VSeWSS Service Error: Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information.

Although I don’t have a true solution for this problem, I do have a workaround. If the DLL that contains the baseclass is in the GAC, then VSeWSS can find it.

 

The workaround

I found that, if you placed the DLL’s that have the base classes and interfaces in the GAC, then VSeWSS can find them. It took me a while to find this out because if you run into this error and then add the DLL into the GAC, then you have to perform an IISReset before VSeWSS finds out that you have added it to the GAC.

I decided to add a post build script to remove and add my files to the GAC. One other challenge I ran into was, that GACUTIL.EXE is not in the same location on every machine. And there is no, easy to use environment variable to find it. So I created a small .BAT file to help me with this.

This is the content of the RegisterInGAC batch file:

 

set gacutil=%programfiles%\Microsoft SDKs\Windows\v6.0A\Bin\gacutil.exe

echo *** RegisterInGac.bat %1 %2
echo * Trying to find GacUtil.exe:

if not exist "%gacutil%" echo * Could not find GACUtil at: %gacutil% 
if not exist "%gacutil%" set gacutil=%ProgramW6432%\Microsoft SDKs\Windows\v6.0A\Bin\gacutil.exe
if not exist "%gacutil%" echo * Could not find GACUtil at: %gacutil%
if not exist "%gacutil%" goto error

echo * Using gacutil.exe from %gacutil%

call "%gacutil%" %1 %2
goto done

:error
echo * Warning: Could not (un)register %2 in the gac.

:done

You can see that it’s trying to find the GACUtil from several locations and it’s telling you which one it’s using.

And to get it to work, I placed this script in the Post build event:

image

My .BAT file is located a couple of levels up in my source tree, so I have to find it there.

Nice side-effect of this approach

I’ve found that there is a nice side-effect to using this approach.

Our packages are also placing some DLL’s into the GAC. However, because assemblies in the GAC take precedence over assemblies on the filesystem, this can cause issues when running unit tests. The unit test will not use the latest version (that you have just built), but it will use an older version that’s still in the GAC. By using this approach, you basically make sure that the version in the GAC is always the latest version.

Hope this helps.

Keep practicing!

Erwin

This week, we published the results of interation 9 to our codeplex site.

You can get it here:

http://spg.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=27299

In this drop, we have addressed a number of tasks:

  • Implemented trusted facade pattern and removed the fake SSO provider
  • Refactored the repositories to make better use of WCF Proxies
  • Support for UpdatePanel in SafeScriptManager
  • Updated PartnerLandingPage
  • Removed most usages of .net 3.5
  • Provided instructions on how to use a host name to access extranet site

Trusted facade pattern

We are demonstrating in our RI how to call back-end services from SharePoint. It’s quite common to have different credentials to log on to back end services.

Replacing the fake SSO provider

Before, we were using a fake SSO provider (Single Sign On) for that. We built a fake SSO provider because it’s actually quite hard and complex to build a real SSO provider. Since the SSO provider should store passwords in a secure way, there are a whole range of attacks you need to watch for. We felt we didn’t want to take on that extra complexity in our project, so we built a fake SSO provider that stored the passwords in clear text. We hoped that calling it ‘fake’ would make it clear enough that this is not something you would want to do in production.

We a lot of feedback that giving an example that shows how to store passwords in clear text is bad. No matter how clearly you explain that it’s not something you want to do in production, somebody is going to do it anyway. But since didn’t want to show you how to build a real SSO provider (that would be a project in itself), we decided to change our implementation to a trusted facade. 

Trusted facade explained

The following diagram shows the trusted facade pattern:

image

A user authenticates with the trusted facade. It validates the credentials provided by the user. Then, if the trusted facade calls the back end service on behalf of the user, it only specifies the username. The back end service trusts the Trusted Facade to provide the correct username, so it doesn’t need to perform any authentication.

We implemented our trusted facade based on this MSDN article. Our implementation looks like this:

image

A user connects to SharePoint either through windows authentication or through Forms Based Authentication (FBA). Then, when the user wants to make a request to a backend system, for example to retrieve the price for a product, the pricing repository will find out what partner the user belongs to. It will then call the back end service with the name of the partner. The pricing service trusts our SharePoint application to provide the correct partner name, so it doesn’t require any passwords. 

Of course, you have to make sure that only the account that SharePoint runs under is allowed to access the pricing service.

Repository refactoring

We took a critical look at our current implementation of the repositories.

The goal of the repositories is to hide data access logic from consumers. For example, we have a ProductCatalogRepository, which has methods like: GetProduct(string sku) to retrieve product information. This repository uses the BDC for some of it’s methods, but for other, it calls into our productcatalog webservices directly. However, the consumers of these repositories don’t know where the data comes from. They also don’t know (and don’t care) that the data is cached.

Webservice proxies

Adding a reference to a webservice is very simple in Visual Studio. What happens under the covers is quite a bit more complex. Visual studio will generate proxy classes based on the metadata that’s returned from the service.

We implemented the following best practices for calling web services:

  1. If your service references are used by multiple projects, create a single project that holds the service references and reference that project.
    There are to reasons for this. If you are making changes to your webservice, you only have to update one service reference. Forgetting to update one can cause annoying bugs. But from a design perspective, if you generate two proxies for the same web service, then you’ll have duplicate (incompatible) types in your system. For example, the price object generated for proxy 1 will be different from the price object generated for proxy 2. Even though they have exactly the same signature, you can’t reuse the types for them or reuse methods that work on them. We implemented this in the Contoso.Pss.Services.Client solution.
  2. Don’t call the service proxies directly, but wrap the calls to the service proxies into repositories or service agents.
    This best practice is used to shield your application from (minor) changes to the service. It does take some extra coding, because you have to transform the objects you get back from the service into objects that can be used by your application. So this practice does adds a level of indirection and extra complexity to your application, so you have to make the tradeoff if the extra complexity is worth the isolation. In general, if the services are created for and only used by your application, you typically don’t need such a level of indirection. However, if you don’t have control over your services or other clients are also using the services, it’s often worth it.

There were a couple of area’s we explicitly didn’t look at.

Getting the repositories from the service locator

Before, we were creating the repositories directly in our code, for example in our presenters. This is often undesirable, because it makes the presenters harder to unit test. Now, we have registered the repositories in our service locator. Therefore, we can use the service locator to get instances of our repositories and we are able to mock out these in our unit tests. Sweet :)

UpdatePanel in sharepoint

SharePoint has a slightly different method for implementing post backs than the normal ASP.Net framework. It uses a custom javascript method that is called on postback. Unfortunately, this means that the Ajax UpdatePanel doesn’t work out of the box, because it also requires a different postback method. The solution is to emit some JavaScript code that intercepts the postback event and calls the normal UpdatePanel posback code.

In order to get the UpdatePanel to work, you need a scriptmanager, because that will add the required javascript code for the async postback to the page. We had already built a SafeScriptManager, that you can add several times to a page without causing issues. So it was natural to add some functionality to it to enable support for the UpdatePanel.

 

Removed most .net 3.5 usages

We were making judicious use of the wonderful new features of .Net 3.5 such as Linq queries, lambda expressions and type initializers. However, we got the feedback from our advisors that .net 3.5 is not widely used by the sharepoint developer community. After many discussions, we agreed that removing most of the .net 3.5 usages would make our guidance a bit more consumable by the sharepoint developer community.

Added instructions on how to use a host name to access extranet site

Lastly, we added some instructions on how to use a host name to access extranet sites. Now, our extranet site is accessable on localhost:9001. If you would prefer to host the extranet site on a hostname, for example extranet.mydomain.com, we have included instructions on how to do that.

Hi guys,

Our drop 8 video is online on Channel 9. Check it out:

Happy watching and keep practicing!

_Erwin

A while ago, I put an example application on my blog on how to build an outlook style application.

The last couple of weeks, I’ve been working on a new version of this app. I’ve done some bugfixes, but also included support for opening use cases in a popup window. It’s turning out to be quite an advanced demo of what’s possible with Prism. But while I’m playing with it, I can’t help but be amazed with the things I can push Prism into doing :)

You can get the source code for my updated version here:

So there are a couple of things I didn’t explain in my previous blog:

  • How to do ViewModel first development?
  • How to open a Use Case in a popup?
  • Why I’m using ObservableObject in my ViewModels?

So here goes:

ViewModel first development

I’m a big van of ViewModel first development. So what does that mean?

  1. I create my ViewModels before i create my Views. This allows me to create testable viewmodels that absolutely don’t rely on any visual aspects.
  2. My application code programs against ViewModels, not Views. Most of my code doesn’t need to know about the views. Only when a ViewModel needs to be displayed should you load up the view to display it.

There are a couple of big advantages to this approach:

  • You can easily unit test your UI logic, without relying on visual elements.
  • I can easily reskin my app.
  • You don’t have to forward data from your views to your view models. This is something I have always found annoying with a View First approach. For example, if you have a view that displays a person and needs a PersonID to do it. With view first, your code has to talk to the view. So the view needs a PersonID property. But actually, the logic of your view needs that PersonID, so it needs to be forwarded to your ViewModel. Annoying, tedious, error prone!!!

I wanted to be able to put ViewModels into my regions and to have some code that would provide the visualization onto it. So the code I want to be able to write is:

// 1: Setup visualizations (typically in Module.Initialize)
// Whenever an EmailMainViewModel is displayed, visualize it with an EmailMainView
modelVisualizationRegistry.Register<EmailMainViewModel, EmailMainView>();

// 2: Add ViewModels to region (view discovery, view injection or any other method)
region.Add(new EmailMainViewModel());

ViewModel First internals

If you’re interested in how I built the ViewModel First code? here it is:

ModelVisualizer

The first step into creating the view model first appraoch was to create a ModelVisualizer class. The reason for this was: "The prism region adapters will put the content of the regions directly into the control that hosts the region (for example, a contentcontrol). There is no extensionpoint to sit in between that.

So I created something that I could put in a region, that would hold BOTH the View and the ViewModel. It would be the glue between the view and the viewmodel and:

  • Set the View as the content in the Visual Tree.
  • Set the ViewModel as the datacontext for the View.
  • Forward common information between the ViewModel and the View (such as the RegionContext or the IsActive values)

The following diagram explains my ModelVisualizer.

image

The ModelVisualizer IS a ContentControl. So it can be placed inside the Visual Tree. It will set the View as the content. It will also set the ViewModel as the datacontext of the view (so the view can bind to all the information in the ViewModel). Lastly, the IModelVisualizer implements the IRegionContextAware and IActiveAware interfaces, and will synchronize these interfaces with the View and ViewModel if they implement the interfaces.

Visualizing Region

The ModelVisualizer worked great. However, it demanded that all my code knew about the ModelVisualizer. I didn’t want to do that, because I wanted to make it implicit. There were some issues with that though, because due to the current implementation the region adapters, I didn’t have an extension point to create my visualizations implicitly. I couldn’t change the type of region that was created by adapters and I couldn’t change how the adapters set the content of the region to the hostcontrol. But I solved that with a little trick, that I call my VisualizingRegion.

The trick was: while I couldn’t change what type of region was being created, I could control what type of region was registered to the RegionManager (because there is a regionbehavior that does the registration. So I just wrapped the Region that was created by the regionadapters in my own region (the visualizing region) and registered my own visualizing region to the regionmanager.

The only way a consumer can get access to the Region is through the RegionManager, so that solved the problem :)

Easier Solution to region context

In Prism V2, we introduced the concept of RegionContext. The RegionContext is a way that a view that hosts a region can share some of it’s information with any childviews that are loaded into it’s region. While I really liked the concept of RegionContext, I didn’t really like the implementation of it.

So I created the IRegionContextAware interface. It has one property (the regioncontext as an ObservableObject) and the RegionContextAwareRegionBehavior that would sync the context of the region with the RegionContextAware properties.

Opening a Use Case (or ViewModel) in a popup

One thing I thought was an interesting challenge was opening a viewmodel in a (non modal) popup. So why would this be challenging:

  • You can have many instances of the same popup open at the same time.
  • Viewmodels shouldn’t know if they are opened in the main window (perhaps in several tabs) or in a popup. This should be decided by the designer, preferably in XAML.

The code I wanted to be able to write is:

   1: // Create an UseCase to write new email messages
   2: NewEmailUseCase newEmailUseCase = ApplicationModel.CreateObjectInScopedRegionManager<NewEmailUseCase>();
   3:  
   4: // Add some data to the Email message use case (in this case, a blank new email)
   5: newEmailUseCase.Message = new EmailMessage();
   6:  
   7: // Show the email (in a popup, but the consumer doesn't know that)
   8: ApplicationModel.ShowUseCase(newEmailUseCase);

The problem with opening several instances of the same popup is: Regions are identified by name in the regionmanager. If you have several popups of the same type open, each popup needs it’s own RegionManager, or else the region names will collide.  In my scenario, I decided that the Popup has most of the same region names as the main shell. That way, any ViewModel or use case could be loaded in either the popup or the main window.

Creating use cases in a scoped regionmanager

Ok, so i need to create a scoped regionmanager. That’s not to hard, just do: RegionManager.CreateRegionManager() and you have one. However, I wanted the consuming code NOT to have to think about this. It should be blissfully ignorant about the fact that it’s in a scoped regionmanager or not.

Since all most of my objects are created by a DI Container, and it injects all of the dependencies to my object, I decided to use that to solve this problem. So I created a scoped Container and registered the scoped regionmanager with that. Then I created my use case from the newly created scoped container, and if it needs a regionmanager, it would automatically get the scoped regionmanager. Pretty neat huh.

So schematic, that looks like this:

image

So when the use case (in green) get’s created, it and it’s dependencies would get the scoped regionmanager injected. Without knowing about the scoped containers or scoped regionmanager.

Adding use cases to popups

Adding the use case to a popup (in the application model) works like this:

image

  1. Create the use case.
    Your code creates a new use case instance, for example new NewEmailUseCase(); The application model has a method to create a use case within a new RegionManager scope (as described before).
  2. Show use case.
    Your code calls the Application model to show the use case.
  3. Add to region.
    The application model (which is logic) doesn’t even know if the use case is displayed in a popup or not. It just adds the use case to a region. The region itself is defined in the Shell.XAML.
  4. Visualize the Use case
    Just as a visualization (view) can be registered for ViewModels, i’ve also registered a visualization for Use Cases. In this case, I’ve registered a window (called Popup.XAML) as visualization.
  5. Show /Close the popup on activate.
    Now that the visualization is there, I had to create some code to show and close the popup. I decided that, if i Activate() the use case, the popup should be displayed. If I deactivate Use case, the popup should be closed and the use case should be removed from the region. This functionality I put in a RegionBehavior, because it can easily monitor if something is added or removed from a region.
  6. Assign scoped region manager to the popup
    Lastly, the popup window needs to know the RegionManager that the Use Case wants to use. So I’ve created the IRegionManagerAware interface. If a usecase implements that interface, anything that’s placed inside the region will get this region manager assigned.

As you can see, there are quite a lot of moving bits for showing a use case into a popup. Of course, it would have been A LOT easier to give ‘your code’ (an other use case or something) the knowledge that a view can be opened in popup. 

ObservableObject for easier binding

If you look at my viewmodels, you’ll see that I make use of the ObservableObject a LOT. It’s a very simple object, one that just takes a type and wraps it in a INotifyPropertyChanged. The nice thing about this is, that I don’t have to add any INotifyPropertyChanged code in my ViewModels anymore. That makes it soooo much easier to do 2 way databinding in WPF.

The only problem is, that to get to the value, you often have to do: viewModel.MyProperty.Value to get to the actual value of MyProperty. But I thought that’s worth it since now I don’t have to write INotifyPropertyChanged code for my properties anymore.

Conclusion

Like I mentioned, before, this outlook style app has become quite an advanced demo of what’s possible with Prism. But I hope it gives you some idea’s on what’s possible with it. I’m also in the process of creating a video walkthrough of this application. But I’ll let you know when that’s done!

Keep practicing!

_Erwin

 

[UPDATE]

If you get an System.Threading.SynchronizationLockException from Unity: Don’t worry! I had turned on ‘break on all exceptions’ so the debugger is also breaking on these handled exceptions. Just continue and the app will run fine, or change that debug setting.

Last Friday, we’ve released drop 8 of our Guidance.

 

What did we tackle in iteration 8

The main theme in drop 8 was exception handling in SharePoint. But we also did a bunch of refactoring in the application:

  • Service locator
    We want to create a true service locator for sharepoint. However, this is a bit lower on our priority list. So for now we have the interface in place and will keep refactoring it in future drops.
  • Ajax support feature
    We already had an feature that allowed you to add Ajax support to your page. We’ve now cleaned up the code a bit more.
  • LOB Services support
    Created LOB Service Support project to deploy web.config modifications required for LOB services

Exception handling

We looked at a bunch of exception handling scenario’s and how they relate to SharePoint.

The general guidance around exception handling still applies to programming in SharePoint. For example:

  • Use exceptions for exceptional situations. Avoid using error codes to signify error conditions.
  • Use specific exception types. Avoid throwing and catching Exception directly like the plague.
  • Only catch exceptions that you can handle.
  • Never ever EVER EVER catch(Exception ex) and swallow it! This can result in bugs that are almost impossible to find! The ONLY place where you can do this, is in an unhandled exception handler where you should:
    • Log the exception
    • Show the user a friendly message: “We’re so sorry, but something went wrong. Please try again later.” or something.
    • Let the application die gracefully.

But please do read the general guidance with regards to exception handling. It’s a good read :)

 

Exception handling in SharePoint

It’s common to have different exception handling strategies for different places in your application. For example, in your web services, you’ll typically apply exception shielding, where you would log the original exception and replace it with a generic error message. An other example would be in your UI, where you would want to log the exception and display a message to a user.

We looked at a couple of these strategies for exceptionhandling in SharePoint where we can apply additional guidance or help. We’ve looked at exception handling in:

  • Pages
    Exception handling in pages in sharepoint is not very different from exception handling in normal ASP.Net, so there is not that much we can provide Sharepoint specific guidance on.
  • Webparts and usercontrols
    Technically, exception handling in webparts and usercontrols in SharePoint is not very differnet from exception handling in asp.net. However, since end-users can create their own pages by dragging several webparts on a page, you often don’t want a single webpart to take down the whole page. So we’ve built an Exception Handling stragety for webparts.
  • ListItemEventReceiver
    If an unhandled exception occurs in a ListItemEventReceiver, what you typically want to do is cancel the action and set the error message. However, if you forget to cancel the action, the change will still continue, which can cause all sorts of problems.  So we’ve built an exception handling stragety for ListItemEventReceivers.
  • Workflows
    It’s pretty easy to implement exception handling in workflows, so we haven’t built anything for it. We’ll probably add some guidelines in our guidance though.

Exceptionhandling in webparts and usercontrols

The default behavior of an unhandled exception in a web part is that the exception will bubble up to the page. There asp.net will redirect to an error page. Since SharePoint allows you to dynamically create pages and add some webparts to them, you might not want a single webpart to take down the whole page. So we’ve built something to allow you to do just that.

We typically apply the Model – View – Presenter pattern to webpart development, because that allows us to easily unit test our UI logic. This pattern looks like this:

image

The webpart loads up a view (an UserControl, to allow for the design time experience). The View loads up a presenter that holds all the UI logic and only communicates to the presenter using a interface (so we can mock out the view during while testing).

So how would we create an exceptionhandler for the webparts that can show error messages? The easiest approach is to allow the view to render error messages:

image

So our Presenter uses an ExceptionHandler to log and show exception messages. However, the (generic) Exceptionhandler needs some mechanism to display error messages. In this case, our view is the only thing our presenter knows. So we gave the view a special interface, the IErrorVisualizer interface, that the ExceptionHandler can use to display the correct error mesage.

You might not want to make the view responsible for showing 'fatal’ error messages. For one reason, makes the view more complicated. Another reason might be, that you would want a consistent way of displaying error messages across all your webparts. In that case, the following pattern might be better:

image

In this case, we’ve created an error visualizer. It’s just a control that knows how to display error messages. It implements the IErrorVisualizer interface. This way, the view is blissfully unaware on how errors are being displayed.

Now, if the presenter wants to call the error message, it not only needs a reference to the IMyView, but also to the IErrorVisualizer.

This is what the code from the presenter looks like:

   1: public void LoadProduct(string sku)
   2: {
   3:     try
   4:     {
   5:         logger.LogDiagnostic("In OnViewLoaded.");
   6:  
   7:         Product product = productCatalogRepository.GetProductBySku(sku);
   8:  
   9:         if (product == null || product.Sku == null)
  10:         {
  11:             // Show an error message to the user
  12:             new ViewExceptionHandler().ShowFunctionalErrorMessage("Could not find product information.", this.ErrorVisualizer);
  13:         }
  14:         else
  15:         {
  16:             this.view.Product = product;
  17:             this.view.DataBind();
  18:         }
  19:     }
  20:     catch(Exception ex)
  21:     {
  22:         // If something goes wrong, make sure the error gets logged
  23:         // and a non technical message is displayed to the user
  24:         new ViewExceptionHandler().HandleViewException(ex, this.ErrorVisualizer, 
  25:             "Due to a technical problem, the product details cannot be displayed.");
  26:     }
  27: }

All the code from the presenter is now in a try catch block. In the catch, we call the ViewExceptionHandler to handle the error. In this case, handling the error means: Log the error and show a ‘friendly’ error message.


Exceptionhandling in ListEventReceiver

Another ExceptionHandling strategy we’ve created is the ListExceptionhandler strategy.

If an unhandled exception occurs in a list, you should take the following actions:

  • Log the Exception
  • Set the ErrorMessage
  • Consider if you should cancel the action. We feel that de default action should be cancel, to avoid any potential harmful entries from entering your list.

So we’ve built a ListItemExceptionhandler that will do that for you.

Conclusion

As always, we hope you like the stuff we’re showing. If you have any feedback, comments or questions, feel free to ask me or the team (through the codeplex forums).

Hi guys,

Last monday, we have released drop 7 of the SharePoint Guidance V2. You can get it here:

http://spg.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=26085

In this drop, we have tackled a couple of things:

  • A couple of bugfixes and installation fixes.
  • Created a Logging and Tracing implementation
  • Added a Service locator
  • Refactored code into a PartnerSiteDirectory class

For your viewing pleasure, we recorded a video to guide you through the drop:

Logging  and tracing

 

For any application, it’s important to write diagnostic messages to a log. Diagnostic information is invaluable when you want to identify and diagnose problems with your application.

While logging and tracing is in some respects similar, the audience and purpose are quite different:

Tracing

Tracing is a technique to help developers analyze and diagnose problems with their application. For a developer who has to hunt down a problem, you can never have too many tracing information. However, because the amount of trace information can be overwhelming (for a developer, but also for the system that has to write all the information), tracing levels should be adjustable at runtime.

What should you trace?

  • Errors and exceptions
    If something goes wrong with your application, you want to know about it. Even if your code can handle the exception, it’s often beneficial to write a trace statement. For example, did a download fail, but you were able to retry. The user might not need to know, but you as a developer might be really interested in this information.
  • Remote system calls
    In a service oriented world, it’s very common for an application to access functionality on a different machine. This is also a place where things go wrong often. Being able to trace the request and response messages can greatly help in debugging what goes wrong. Many frameworks, such as Windows Communication Foundation, allows you trace this information.
  • Queries
    If your system is creating and executing queries, the text and the parameters of these queries can be a life saver when debugging an application. Note, queries are not limited to SQL queries against a database. Also consider CAML, Entity SQL and any other querying syntax that your app might use.
  • Anything else you think is important
    There are a lot of other things that can be helpful for debugging. Use your imagination :)

Typically, tracing information goes to a log file on the machine that does the tracing.

Logging

Logging is a technique to help IT pro’s to detect, diagnose and troubleshoot problems with their applications. Often this information will be aggregated into a central monitoring system like Service Center Operation Manager (SCOM).

Information written to the log should be understandable and actionable by IT Pro’s. A message like “Object reference not set in method Foo()” can be helpful for a developer, but doesn’t really say anything to an IT Pro. However, a message like “Could not connect to database X, the connection timed out.” does make a lot of sense to an IT Pro.

What should you log?

  • Known application failures
    Often there are situations where you can expect your applications to fail sometimes. For example, you’re calling web services. If there are network issues, the web service call will fail. This would be something the IT would be interested in.
  • Installation or configuration issues
    If the installation or configuration of your app fails, the IT Pro wants to know about it. Usually they are the persons that do the installation and configuration.
  • Unknown application failures
    If your application faces an unhandled exception, usually the IT Pro just wants to be informed that a certain area of the application is having issues. For example: “Authentication failed for unknown reason”.
  • Situations that can potentially cause issues in the future.
    Sometimes you can proactively detect issues. For example, “the hard drive is becoming full. “ or “Deadlock detected in query x”. The application will often still work, but it can be an indication of deeper issues.
  • Other actionable information.
    Again, this is not an exhaustive list. Be creative but keep your audience in mind :)

Typically, log information is stored in the EventLog, because this is easily consumed with tools like SCOM. However, some organizations might prefer storing this information in a central database.

Logging and tracing in Drop 7

In Drop 7, we have built a basic logging and tracing implementation.

The idea of this logging implementation is that you have a logging and tracing implementation that works out of the box. However, if you need more flexibility or have an existing logging implementation, you should be able to plug that in. For example, we’re thinking of supplying an Enterprise Library logging implementation for Sharepoint. If you don’t know or care about EntLib, you shouldn’t have to bite off the extra complexity that entlib brings. But if you need to, you should be able to plug it in easily.

The following code snippet shows how to use the logging API:

   1: ILogger logger = new SharepointLogger();
   2:  
   3: // Write a diagnostic statement (just to the ULS)
   4: logger.LogDiagnostic("Just executed query: " + camlQuery);
   5:  
   6: // Write a warning and a error message (both to the ULS and the EventLog)
   7: logger.LogWarning("Sharepoint list exeeds 2000 items. Listname = " + listName, SHAREPOINT_LIST_EXCEEDED);
   8: logger.LogError("Could not connect to database: " + databaseName, DATABASE_CONNECTION_EVENTID); 
   9:  
  10: // General purpose API
  11: logger.Log("logmessage", TraceSeverity.Verbose, myEventID, "MyCategory")

There are several methods like LogDiagnostic, LogWarning and LogError, that are explicit about the specific log scenario.

For our basic logging implementation we took the following approach:

  • Warnings and errors should go to both the EventLog and the tracelog (ULS)
  • Diagnostic messages should only go to the (ULS).

We decided to use the ULS for our tracing. This allows a developer to see his diagnostic messages in the context of sharepoint’s trace messages. If the developer is trying to diagnose a problem that is caused by an issue in sharepoint, he can more easily find the root cause.

Event sources for logging to the EventLog

When we are logging to the eventlog, you need to write to a specific Event Source. An Event Source specifies the name of an application that is allowed to write to the eventlog. Unfortunately, the asp.net user account by default doesn’t have the rights to create new event sources. So either you should allow the asp.net user to create the eventsources or you should pre create event sources on all your web servers.

For now, we took the approach of (ab)using the “Office Sharepoint Server” event source, because this should be available out of the box. In a future drop, we probably want to be able to configure the event source and probably the application log name.

Service locator

In your application code, you often need to have access to system level services. For example, you want to log messages or you want to do some type of data access and need a specific repository. Of course, you can new up the concrete implementation your service in your application code. However, if you want to be able to plug in different services, you’d need to change all the places where you’ve created the services.

A better way is to hide creation of services in a service locator. Instead of using:

SharepointLogger logger = new SharePointLogger()
logger.LogError("Wrong!");
 
You could do this:
 
Ilogger = new ServiceLocator.Current.GetInstance<ILogger>()
logger.LogError("Wrong!");

Now, your application code is no longer tied to any specific implementation of logger.

We have included a very simple ServiceLocator in this drop. It hard codes the coupling between the interfaces and their implementations. Still, this provides a lot of benefits, because the which concrete implementation is used is defined in a single location. The interface of this class was created using the interface from the Common Service Locator project.

In a future release, we might use a different technique. For example, we might build our own configuration based service locator or use Unity and the Common Service Locator for this.

Partner directory

While developing the Reference Implementation, we found a number of  places where we needed to know the ID of the currently logged on partner, or the URL to it’s collection. Since this information is stored in a central location, we decided to create a helper class to encapsulate this information.

Currently, the partner site directory has only public static methods, but now that we have a service locator, we can create this as a service behind a interface and use the service locator to find it. We’ll tackle that in a future iteration.

Conclusion

We hope you think the things we have been working on in this release are useful. Let us know what you think.

In the next release, we are looking at tackling (among other things) exception handling.

Keep practicing!

_Erwin

[Update] 

I’ve posted a workaround to this issue here: http://blogs.msdn.com/erwinvandervalk/archive/2009/06/08/using-interfaces-and-base-classes-in-different-assembly-using-vsewss-1-3.aspx. 

[Original post] 

One of the common practices I try to follow is: Program to interface, not implementation.

It allows you to decouple components from each other and easily plug in different implementation. This is great for test driven development, where you can replace all the dependencies of the object under test with Mock objects.

But when I tried to do something similar in our Sharepoint Guidance project, I ran into a problem with the Visual Studio Extensions for Windows Sharepoint Services (VSSeWSS) 1.3.

The problem

I had created two assemblies, one with an interface definition and the other with the actual implementation. Seems pretty basic, but when I tried to use it to create a WSP package, I got the following error:

Error    1    VSeWSS Service Error: Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information.

Log file written to: C:\Windows\system32\config\systemprofile\AppData\Roaming\Microsoft\VSeWSS 1.3\VSeWSS1.3 service.log        0    0   

Ok, maybe the log file explains what’s wrong?

2009/04/10 11:13:59    Error
System.Reflection.ReflectionTypeLoadException: Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information.
   at System.Reflection.Module._GetTypesInternal(StackCrawlMark& stackMark)
   at System.Reflection.Module.GetTypes()
   at Microsoft.SharePoint.Tools.Reflection.ModuleWrapper.GetTypes()
   at Microsoft.SharePoint.Tools.Reflection.TypeFinder.GetTypesAsType(IAssemblyWrapper assembly, ITypeWrapper targetType)
   at Microsoft.SharePoint.Tools.Reflection.TypeFinder.Find(IAssemblyWrapper assembly, ITypeWrapper targetType)
   at Microsoft.SharePoint.Tools.SharePointProxies.WSPViewFacade.CreateWebPartReferenceResolverClassMap(String[] paths)
   at VSeWSS.Server.Services.SPService.CreateWebPartReferenceResolverClassMap(String[] paths)

How incredibly useful.

The solution

After a lot of puzzling, I found out that the VSSeWSS 1.3 tool has problems with separating the implementation and interfaces in seperate DLL’s. Even if you reference the DLL’s, but not add project references, it gives the previous error message when packaging it.

However, i found if you set ‘copy local’ to False in the assembly references, the problem goes away. Of course, it does create another problem. How do you get the dll’s on sharepoint.

The solution I’m going to take is: Create a feature that puts the DLL’s on the server. Create another feature that wants to use the dll’s, but has ‘copy local’ to false. I know, it’s not pretty, but it works.

Hope this helps,

_Erwin

Hi Guys,

Last week, we have released drop 6 of the Sharepoint guidance V2. In this drop, we have tackled the following subjects:

  • Several ways of doing list access
  • Caching BDC data and published pages
  • Using powershell to query sharepoint workflow associations

Here’s a video where Francis and I are talking about what’s in this drop

 

List access

There are a lot of ways to query list data. The most common way is to use the Content Query WebPart (CQWP). This webpart allows you to create a query against most sharepoint data. In previous drops, we’ve already demonstrated how to use the CQWP to query data. However, there are things the CQWP can’t be used for. In this drop, we’ve demonstrated some of those techniques:

Using the Portal Sitemap Provider to access list properties

The CQWP cannot access additional properties that can be stored on sharepoint objects such as lists and sites. You can use the Portal Sitemap Provider (PSMP) to get access to some of these items.

From MSDN: The Portal Sitemap Provider provides PortalSiteMapNode objects that represent a merging of the Windows SharePoint Services 3.0SPNavigation store and dynamic site structure, including sites and pages.

Since the PSMP also caches it’s data, it’s much more performant than querying all SPSite objects directly.

In our Reference Implementation, partners can create sites to collaborate in resolving issues with some of Contoso’s products. These sites are linked to a specific incident and we’d like to get an overview of the status of the incident.  So we are using the PSMP to get a list of all incident sites, with their status. The following codesnippet shows how we are doing that:

   1: PortalSiteMapProvider provider = PortalSiteMapProvider.CombinedNavSiteMapProvider;
   2: if (provider.CurrentNode != null && provider.CurrentNode.HasChildNodes)
   3: {
   4:     var nodes = provider.GetChildNodes(provider.CurrentNode).OfType<PortalWebSiteMapNode>();
   5:     var incidentNodes = from node in nodes
   6:                         where node.GetProperty("businessevent") != null &&
   7:                               node.GetProperty("businessevent").ToString().ToLower() == "incident"
   8:                         select new
   9:                         {
  10:                             Title = node.Title,
  11:                             Url = node.Url,
  12:                             Status = node.GetProperty("status"),
  13:                             CreatedDate = node.CreatedDate,
  14:                             LastModifiedDate = node.LastModifiedDate
  15:                         };
  16:  
  17:     view.Data = incidentNodes;

 

Using the Object Model to access targetted lists across site collections

You can only use the CQWP and PSMP within a Site Collection. But what if you want to access data across site collections? If you want to access a specific list in a different sitecollection, the easiest way to do this is to use the Sharepoint object model.

In our Reference Implementation, each partner has it’s own sitecollection. On some pages, we’d like to show promotions, which are stored in a central SiteCollection.  Since we know which list to query, using the OM is the easiest approach. The following codesnippet shows how to open the site  that contains the list. The URL we are passing in determines which site in which sitecollection we are targeting. Note that we have to dispose the SPWeb that we have opened again.

   1: using (SPSite site = new SPSite(siteUrl))
   2: {
   3:     using (SPWeb web = site.OpenWeb())
   4:     {
   5:         if (web != null)
   6:         {
   7:             partnerPromotions = this.QueryForPages(web);
   8:         }
   9:     }
  10: }

Now once we have hold of the SPWeb, we can fire a query against it. That’s fairly straigtforward. Just fire a CAML query against it. We’re then populating a list of strongly typed objects that we can show in our Views:

   1: private List<PartnerPromotionEntity> QueryForPages(SPWeb web)
   2:  {
   3:      List<PartnerPromotionEntity> partnerPromotions = new List<PartnerPromotionEntity>();
   4:  
   5:      SPList pagesLibrary = web.Lists["Pages"];
   6:      if (pagesLibrary != null)
   7:      {
   8:          SPQuery query = new SPQuery();
   9:          query.Query = string.Format("<Where><Eq><FieldRef Name='ContentType'/><Value Type='Text'>{0}</Value></Eq></Where>", "PromotionPage");
  10:          SPListItemCollection items = pagesLibrary.GetItems(query);
  11:          foreach (SPListItem item in items)
  12:          {
  13:              partnerPromotions.Add(new PartnerPromotionEntity
  14:                                         {
  15:                                             ImageTag = item["ProductImageField"] == null ? string.Empty : item["ProductImageField"].ToString(),
  16:                                             PromotionName = item["PromotionNameField"] == null ? string.Empty : item["PromotionNameField"].ToString(),
  17:                                             PromotionUrl = string.Format("{0}/Pages/{1}", web.ServerRelativeUrl, item["LinkFilename"])
  18:                                         });
  19:          }
  20:      }
  21:  
  22:      return partnerPromotions;
  23:  }

Note that we’re using the GetItems(query) method. This is MUCH more performant than using the Items property. Usually, it’s much better to use the GetItems method than the Items property, because the items property will return ALL the data for that item. For large lists, with many columns, this becomes very slow!

Using search to query a lot of lists across site collections

In the previous example, we knew we wanted to target a single list in a different site collection. However, what would happen if you want to query infomation scattered around several sitecollections. For example, we want an overview of all incident tasks in the Contoso RI. However, these incident tasks are scattered around the incident sites for different partners (in different site collections).

If you wanted to query something like that using the Object Model, you’d need to iterate over all sites and lists to find the information. Then you’d better invest in a LOT more hardware ;) A better approach is using Sharepoint Search to find this information. The nice thing about Search is, that it is VERY fast. However, it will not give you a real time overview the data. Search uses a search crawler to index it’s data. So depending on your configuration of the search crawler, some of the information can be out of date.

We figured however, that for getting an overview of the Incident Tasks, It’s not really a problem if the results are not real time.

The following code example shows how we’ve implemented this. We are creating a Sharepoint Search Query and firing it at the Sharepoint Search Engine. The results, we’re putting into a list of objects and showing them in our View.

   1: StringBuilder query = new StringBuilder();
   2:  query.Append("SELECT Path, Title, Description, ContentType FROM SCOPE() ");
   3:  query.Append("WHERE \"SCOPE\"='All Sites' AND ContentType = 'Incident Task' ");
   4:  query.Append("ORDER BY Path ASC");
   5:  
   6:  FullTextSqlQuery sqlQuery = new FullTextSqlQuery(ServerContext.Current)
   7:                                  {
   8:                                      QueryText = query.ToString(),
   9:                                      ResultTypes = ResultType.RelevantResults
  10:                                  };
  11:  
  12:  ResultTableCollection queryResults = sqlQuery.Execute();
  13:  DataTable resultsTable = new DataTable();
  14:  resultsTable.Load(queryResults[ResultType.RelevantResults]);
  15:  
  16:  var results = from DataRow datarow in resultsTable.Rows
  17:                select new
  18:                {
  19:                    Path = datarow[0] == DBNull.Value ? string.Empty : (string)datarow[0],
  20:                    Title = datarow[1] == DBNull.Value ? string.Empty : (string)datarow[1],
  21:                    Description = datarow[2] == DBNull.Value ?string.Empty : (string)datarow[2]
  22:                };
  23:              
  24:  this.view.Data = results.ToList();

Caching

In this drop, we’ve looked at some caching scenario’s. Apart from the normal ASP.Net caching guidance, there are several specific things you could do with regards to caching in sharepoint.

Caching Business Data Catalog Data

The Business Data Catalog (BDC) is a way of exposing data from several data sources (for example databases or webservices) to sharepoint. Then, this data can be queried using out of the box webparts or indexed using Sharepoint Search. This is a very powerful concept. However, the BDC doesn’t support caching.

From the perspective of a webpart, the BDC is a datasource. It’s usually recommended to encapsulate data access logic in separate classes, for example by using the repository pattern.  So what we’ve done is to encapsulate the calls to the BDC in a repository. Now this becomes a handy and centralized place to implement caching.

Note. All of your custom webparts are using the repository, but of course, the out of the box webparts are still calling the BDC directly.

Caching published pages

We’re also demonstrating how to cache published pages.  This is done through configuration and has to be turned on in a feature receiver.

Using Powershell to query sharpoint object model

Once you have deployed your application, with stuff like webparts and workflows in it, people will start using them in production. They’ll take the sharepoint designer and start building the functionality they need. But now if you want to upgrade your functionality, they run the risk of loosing their customizations.

Unfortunately, there is no way to package those customizations that are made in a production environment. But there are tools available to at least detect for example where your webparts are being used. What we’re demonstrating in this drop is how to do the same for workflow assiciations.

Conclusion

I hope you find what we’re demonstrating in our RI useful. In the next couple of drops, we’re going to demonstrate how to do stuff like logging and exception handling, so keep tuned!

As always, any feedback is welcome :)

Prism has been out for quite a while now. I hope you had some time to play with it, read the docs, look at the code and build apps with it. So, what do YOU think of prism? Did you like it? Did it help solve your composite application problems? Was it easy to use or very hard? Please let us know by filling out this survey:

http://www.zoomerang.com/Survey/survey-intro.zgi?p=WEB228YSYYRK4A

Of course, you don’t have to.. but this is your chance. If you really liked prism, then tell us. That way, we know we have to invest more in future versions of Prism ;)

Since the Prism project is done, I’ll be working on a different project for the next couple of months.

Sharepoint guidance on Codeplex

The goal of this project is to provide guidance on how to build Sharepoint applications in a professional way.

Version 1 of Sharepoint Guidance

V1 of the Sharepoint guidance project focused mainly around the following aspects:

  • How to work with development, testing and production environments.
  • How to build sharepoint solutions in a Test Driven fashion.
  • How to set up a Continious Integration environment, that does our Builds, and runs our Unit and Acceptance Tests
  • How to build Sharepoint applications that can be versioned.

To do this, we’ve built a reference implementation that demonstrates all of these concepts.

Version 2 of Sharepoint Guidance

We are now well on our way with the Sharepoint Guidance and are already in iteration 6 (we have two week interations).

In V2, we have the following goals:

  • How to design and build content driven applications
    • How to develop an application that allows a mixture of development activities and authoring.
    • How to create composite
  • How to extend existing LOB systems:
    • How to integrate LOB systems in a secure way using Single Sign-On (SSO)
    • How to manage connectivity with LOB systems and databases by using the Business Data Catalog (BDC) and call Windows Communication Foundation (WCF) from Sharepoint. 

Sharepoint Guidance V2 – Drop 5

Last Friday, we’ve released drop 5 to codeplex. You can download it from here:

http://spg.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=24674

The most important things we have addressed in this drop are:

  • How to implement global navigation, across different site collections. 
  • How to implement custom navigation.
  • How to add Silverlight controls to your site.

Francis cheung and I have created a webcast that guides you trough some of the things we did in drop 5:

 

Global navigation

In our reference implementation, we’re demonstrating how to create consistent navigation across different sites and site collections. It’s very simple to create a sitemap for a single site, by creating a sitemap.xml and using the asp.net sitemap control to create the sitemap and add it to your site. However, creating a sitemap that’s shared between all sites is a bit harder.

The structure of our reference implementation is as follows:

image

We have a sitecollection for our intranet site, a sitecollection for our extranet site and a sitecollection for partner specific sites. Partners who log on to their homepage, will likely navigate between pages on their site and pages on the extranet home, for example to view products or promotions.

We want the global navigation structure to look somewhat like this:

image

The partner should be able to seamlessly navigate between each part of our Sharepoint site. Of course, we only want to have the structure of our site stored and versioned in one place. So to create a consistent story across multiple pages, we have taken the following steps:

  • Created a Sharepoint deployment project to create a feature that will apply a masterpage (with the website’s branding). This masterpage also contains a sitemap control that points to the SPXmlContentMapProvider:
    <asp:SiteMapDataSource ShowStartingNode="false" 
        StartingNodeUrl="/pssportalroot" SiteMapProvider="SPXmlContentMapProvider" 
        ID="contosoPssSiteMap" runat="server" />

  • Create a Sitemap xml file that will be placed 12 hyve. To do that, you have to put it in the folder Templates\Layouts folder.

    The sitemap xml looks like this:
    <?xml version="1.0" encoding="utf-8" ?>
    <siteMap>
      <siteMapNode title="" url="/pssportalroot">
        <siteMapNode title="Partner Home" url="/_layouts/contoso/partnerredirect.aspx?page=Home">
          <siteMapNode title="Manage Incidents" url="/_layouts/contoso/partnerredirect.aspx?page=incidents" />
        </siteMapNode>
        <siteMapNode title="Product Catalog" url="/sites/pssportal/productcatalog/category.aspx?categoryid=0"/>
        <siteMapNode title="Promotions" url="/sites/pssportal/promotions" />
        <siteMapNode title="Search" url="/sites/pssportal/search" />
      </siteMapNode>
    </siteMap>

  • Create a featurereceiver to merge the sitemap xml fragment into sharepoints global sitemap. To do that, call the following method in the FeatureActivated method of the FeatureReceiver:

    web.Site.WebApplication.Farm.Services.GetValue<SPWebService>()
        .ApplyApplicationContentToLocalServer();

Custom sitemapprovider

We are also demonstrating how fill a sitemappath control with custom data and we are using the business data catalog for that.

In our scenario, the business data catalog provides a list of categories and products (which it gets from WCF webservices in a different system). It then uses this data to create category and product pages to display the individual catalogs and products.

We’ve created a custom sitemap provider that will retrieve the categories and url’s to the category pages from the BDC. We then tie a normal asp.net sitemappath control to that sitemap provider to display a ‘crumb’ path  that displays sitemap information.

Silverlight Controls

In our reference implementation, we are also demonstrating how to add silverlight controls to your site. To a ‘normal’ asp.net webapplication, adding silverlight controls is really easy, because the IDE takes a lot of things out of your hands. In Sharepoint, unfortunately that’s not as easy. So if you want to use the Serverside Silverlight controls (in System.Web.Silverlight, from the Silverlight SDK), you will also need to have Asp.net Ajax support in your site. This means: Adding the required entries to the web.config and adding a scriptmanager control to your page.

Web.config changes

There are basically two ways to make changes to the web.config of a sharepoint server. Programmatically, through the API or declaratively, in a XML file. Since there are quite a few changes you have to make to your web.config, we figured the declarative approach works best. Again, you have to call ApplyApplicationContentToLocalServer() to merge the declarative changes into the web.config. I’ll write a later blogpost or do a webcast on how to do this in more detail.  But if you are interested, you can always look at our drop.

SafeScriptManager

The scriptmanager proved to be an issue. You can only have 1 scriptmanager on your page and it must appear before any controls that need it. Normally, you would add a scriptmanager to your masterpage and be done with it. However, sharepoint is quite dynamic with it’s masterpages. You can easily create a new masterpage and use it as the default masterpage for some group of pages. So this means that if you use ajax in some of your webparts, you can no longer use those webparts on pages that don’t have a scriptmanager.

So we’ve created a control called the SafeScriptManager. You can safely add it to any controls or webpart that needs a scriptmanager. It will check if a scriptmanager is already present.

Conclusion

I hope this clarifies a bit what we have done in this drop. I plan on doing a blog post and a webcast for each drop from now on. As always, any feedback (on the post, on the drop or on the weather) are welcome :)

Happy coding!

I found myself today working on a LINQ query that, in my opinion violated the DRY principle.

 

 

Don't Repeat Yourself (DRY, also known as Single Point of Truth) is a process philosophy aimed at reducing duplication, particularly in computing. The philosophy emphasizes that information should not be duplicated, because duplication increases the difficulty of change, may decrease clarity, and leads to opportunities for inconsistency. DRY is a core principle of Andy Hunt and Dave Thomas's book The Pragmatic Programmer. They apply it quite broadly to include "database schemas, test plans, the build system, even documentation."[1] When the DRY principle is applied successfully, a modification of any single element of a system does not change other logically-unrelated elements. Additionally, elements that are logically related all change predictably and uniformly, and are thus kept in sync.

(Source Wikipedia)

 

It’s such a simple principle, and can be really effective if you apply it properly.

In TSQL stored procedures, it was often quite hard to prevent duplication. Consider the following example:

   1: SELECT FIRSTNAME, LASTNAME, ADDRESS
   2: FROM PERSON
   3: WHERE ID = @ID
   4:  
   5: SELECT FIRSTNAME, LASTNAME, ADDRESS
   6: FROM PERSON
   7: WHERE LASTNAME LIKE '@NAMEFILTER' + "%"
   8:  
   9: SELECT FIRSTNAME, LASTNAME, ADDRESS
  10: FROM PERSON
  11: WHERE LASTNAME LIKE '@NAMEFILTER' + "%"
  12: AND AGE BETWEEN 18 AND 24

At first, there doesn’t seem to be too much wrong with these queries.

However, they grossly violate the DRY principle. But in TSQL, it’s hard to reduce this duplication. Sure, you can create helpers like views, SQL functions or table valued functions, but it still is quite hard. Unfortunately, this means that some people feel this is a ‘get-out-of-jail-free-card’ to write long and ugly code. If you have ever had to debug a query that spanned 3 pages in the query analyzer, you feel my pain.

Now with C# 3.0 and LINQ, we get the power of a SQL like query language, right in our C# code. Unfortunately, I’ve seen too often that people just ignore the DRY principle again when creating LINQ queries.

Calling methods from LINQ queries

Yes, you can call methods from LINQ queries. For example, I noticed the following lines of code:

   1: var match = from discountRow in this.pricingDataSet.Discount
   2:             where discountRow.Id.ToString() == id
   3:             select new Discount
   4:             {
   5:                 Id = discountRow.Id.ToString(),
   6:                 PartnerId = discountRow.PartnerId.ToString(),
   7:                 ProductSku = discountRow.ProductSku.ToString(),
   8:                 Name = discountRow.Name
   9:             };
  10:  
  11: var match = from discountRow in this.pricingDataSet.Discount
  12:              where discountRow.Name == name
  13:              select new Discount
  14:              {
  15:                  Id = discountRow.Id.ToString(),
  16:                  PartnerId = discountRow.PartnerId.ToString(),
  17:                  ProductSku = discountRow.ProductSku.ToString(),
  18:                  Name = discountRow.Name
  19:              };

And there were 3 other queries just like it. The filter condition was different, but the select statement identical. So what do you do in a case like this? Right, remove the duplication and call a creation method instead:

   1: public Discount GetDiscountById(string id)
   2: {
   3:     var match = from discountRow in this.pricingDataSet.Discount
   4:                 where discountRow.Id.ToString() == id
   5:                 // Call a method here, instead of duplicating the creation logic everywere
   6:                 select CreateDiscount(discountRow);
   7:  
   8:     return match.FirstOrDefault();
   9: }
  10:  
  11: private Discount CreateDiscount(PricingDataSet.DiscountRow discountRow)
  12: {
  13:     return new Discount
  14:     {
  15:         Id = discountRow.Id.ToString(),
  16:         PartnerId = discountRow.PartnerId.ToString(),
  17:         ProductSku = discountRow.ProductSku.ToString(),
  18:         Name = discountRow.Name,
  19:         Value = discountRow.Value
  20:     };
  21: }

This makes things a lot cleaner to read :)

Composing LINQ queries

Ok, so you can call methods from LINQ. When you create a LINQ query, you are actually creating an expression tree, that will only get resolved the first time you actually execute the query. This allows you to really fun stuff. Look at this example:

   1: var query = from discountRow in this.pricingDataSet.Discount
   2:                   select discountRow;
   3:  
   4: if (id != null)
   5: {
   6:     // Only apply filtercondition when needed
   7:     query = from discountRow in query
   8:             where discountRow.Id.ToString() == id
   9:             select discountRow;
  10: }
  11:  
  12: var match = from discountRow in query
  13:             select CreateDiscount(discountRow);
  14:  
  15: return match.FirstOrDefault();

In this example, I’m only applying the filter condition if I need to have it applied. Try doing that in TSQL! OK, in this example, I haven’t really improved the code, but with more complicated queries, you can do really cool stuff! You can create several filter methods, which you can reuse and between lots of similar queries.

 

Conclusion

LINQ might look like SQL, but in fact, it’s much more flexible and much less dry!

Last week, Bob and I have recorded a couple of webcasts. In these webcasts, we are creating an modular application that aggregates search results from Digg and Twitter.

Part 1: Modules and a shell

In the first part, we are demonstrating how to create a Shell and how to create a module for the Digg Searching. We are also creating a bootstrapper that will instantiate the Shell and locate the modules.

Part 2: Visual Composition

After the shell and modules are created, we have to make sure that the visual pieces (views) are displayed in the right place. We’re not actually implementing the views yet, but we are creating named regions in the shell and loading an empty view from the Digg Module. We are demonstrating how to use View Discovery to load a view into a region.

Part 3: Implementing views and services

In this part, we are actually implementing the Digg Search results view and Digg search service. To do this, we are using the Unity Dependency Injection container to create the views and services.

Part 4: Decoupled communication

Lastly, we are setting up communication between the searchmodule and the diggmodule. We are using EventAggregator to communicate this knowledge.

Here’s the sourcecode for these webcasts:

I hope you like these webcasts. We are thinking of doing other webcasts, like:

  • How to build a Prism V2 app using TDD.
  • How to do remote module loading.
  • How to build an outlook style app (see my previous post :)).
  • Or something else?

Let me know what kind of webcast you (yes YOU) would like to see.

Keep practicing!

_Erwin

[Update] This is part 1 of this post. Read the second post here.

At the end of building prism V2, we have played around with different application styles to see how easy it is to consume our own libraries. In this blog post, I’m going to describe my attempt at creating an outlook style application. My implementation shows the following aspects:

  • How to create application parts that can be activated and deactivated, can be put in a list, and are very lightweight.
  • How to use an Application Model?
  • How to do pure ViewModel first development. In WPF, you can apply implicit Data Templates to visualize objects, but in silverlight that doesn’t work. So I’ll demonstrate two ways to do this.
  • How to handle RegionContext in a more direct way.

You can download the Source Code here:

Of course, the source code is provided ‘as is’ with no warranties.

[Update] There is a new version of this source code available in the second post for this article.

 

Requirements

So what are my requirements for the outlook style app.

  • Be able to show a list of buttons that can activate parts of an application (like the outlook buttons for Mail, calendar, contacts, etc.)
  • It should be possible to activate and deactivate ‘Application parts’. If an application part becomes active, It’s initial view should show up in the main area.
  • Only one ‘application part’ can be active at any point in time.
  • When a view or an application part becomes active or inactive, other views might also have to be added or removed, such as toolbars.
  • Show a list of available ‘application parts’, without really instantiating all their views immediately. Only instantiate the views the first time you show them.

Solution

So this is my Outlook style app:

image

With a little bit of imagination, I hope you can see how this app could resemble outlook ;)

The following diagram shows the overall structure of the application and the most important pieces.

image

My shell has several regions, each brightly colored to make it clear where they are.

The ApplicationModel defines that the application has a list of UseCases. The ButtonBar (in red) is bound to the list of use cases. Each use case is represented as a button. When you click that button, the ActivateUseCase command is fired which will activate the selected UseCase.

An UseCase (like the MainEmailUseCase) implements the IActiveAwareUseCaseController and likely inherits from ActiveAwareUseCaseController. This makes it activatable (I know, it’s not a word). Lastly, the EmailUseCase itself defines which views it needs and where those views should go.

In the following paragraphs, i’m going to describe some of the moving pieces of this design.

Application model

The approach I took when creating the OutlookStyle app is to have a central ‘application model’ that knows how the application is structured. The modules also know a bit about this application model, through the IApplicationModel interface.

The ApplicationModel has a list of Main Usecases (more on usecases later), that I could bind my list of buttons to. It also has a command that can activate a UseCase when one of the buttons is clicked.

Using an ApplicationModel is kind of a double edged sword. It ties you somewhat down to a specific style of application. This makes your modules less portable, but it also makes the interaction between your modules and your shell more explicit and thus easier to understand. Using an application model is only one approach to creating an outlook style application and there are many others. But I thought it was an elegant solution and since we weren’t showing how to create an ApplicationModel in the Prism RI or the Quickstarts I thought it would be nice to show it here.

Internally, the application model uses a SingleActiveRegion to store the UseCases. This might seem strange, but a Region is nothing more than a model that can store a collection of objects that can be added, removed and activated. The SingleActiveRegion is ideal for this purpose, because it will make sure only one usecase is active at a given time. I choose not to add the region to a regionmanager, because I want the ApplicationModel to control access to this region.

 

Showing application parts: UseCaseControllers.

My implementation for the ‘application parts’ that can be activated and deactivated are called ‘UseCaseControllers’. This were my requirements for them:

  • I want to be able to put it in a list bind a collection of buttons to
  • I want to be able to activate and deactivate it.
  • It should be very lightweight, because all available controllers will be activated at once.

Motivations for naming the ‘application parts’

It was quite hard to find a right name for the ‘application parts’:

  • It’s not a module, because a module will likely contain many application parts. Also, a module should be viewed as a unit of deployment.
  • It’s not a view, because it’s more likely a set of views, working together to fulfill a single use case. These views, can be main views, tool bars, etc..
  • I considered the term ‘feature’ for a while. However, if you have ever built installers, you’ll know that a feature is also an overloaded term. It also refers more to a unit of deployment than what we’re looking for here.

So called my ‘Application parts’ UseCaseControllers. In my example, the main buttons on the outlook app kind of map to the ‘main’ or initial UseCases in my application.

Why call it controller? Controller is quite an overloaded term, because of the Model View Controller pattern. However, controllers are also commonly used to coordinate some kind of process and couple several pieces together to form a single unit. So because the controller hooks several controls together to perform a single use case, I called it a UseCaseController.

ActiveAwareUseCaseController

The ActiveAwareUseCaseController is a handy base class that you can use to fulfill the IActiveAwareUseCaseController interface. It does the following things for you:

  • BeforeFirstActivation Method. Have a handy place for the first time you activate this controller. In this method (BeforeFirstActivation), you can create all your Views or ViewModels and perform any eventwiring. For example, tie any toolbar commands to your ViewModels. The ObjectFactory also helps with this.
  • ViewToRegionBinder. One of the things you are very likely to do is to add views to some regions when the UseCase becomes active, and remove them again when it becomes inactive. Instead of having to put region.Add(view) and matching region.Remove(view) calls in the activate and deactivate methods, I figured it would be handy to create one registration method that takes care of this.

Using the ViewToRegionBinder to add and remove views to and from regions

Adding and removing views from a region whenever something becomes active or inactive can be quite tedious. Whenever a view or usecase (or anything else that implements IActiveAware) becomes active, you probably have to find the right regions, add the views to the regions. And the same if the usecase is deactivated (but then remove the views)

To make this a bit easier, I have created the ViewToRegionBinder. This object can monitor an IActiveAware object (such as a IActiveAwareUseCaseController or a view or a ViewModel). You can register a list of objects (views or viewmodels) against names of regions so that, when the object you are monitoring becomes active, the views will be added to the right regions and removed when the object becomes inactive.

   1: // Make sure the Toolbar and the mainregion get displayed when this use case is activated
   2: // and removed again when it becomes inactive. 
   3: this.ViewToRegionBinder.Add("ToolbarRegion", this.emailToolBarViewModel);
   4: this.ViewToRegionBinder.Add("MainRegion", this.emailViewModel);

Using the ObjectFactory to delay creation of your views until you actually need them

Another interesting challenge I ran into was:I wanted to shows a list of buttons for each usecase in my system. But only when I click one of these buttons do I want my views to be created and initialized. You can imagine, if you have 20 of these ‘main’ usecases and each creates a bunch of views when the application starts, application load time would be dramatic.

This was one of the motivations for creating the UseCaseControllers in the first place. They are very lightweight and I could create the views I needed in the Activate() method. But then I faced an other issue. I really like to create my views and my viewmodels using Constructor Injection. However, since the objects injected the constructor would be created before the usecase would be created, not after, i had to put in some level of indirection.

This is what the ObjectFactory<Type> solves. You can express the dependency on an object in the constructor, and create the object when you need it, by calling the ObjectFactory.CreateInstance() method. You can access the instance created by the objectfactory using the ObjectFactory.Value property.

Now I didn’t want to create member variables for the ObjectFactories, because that would mean that every time I needed to access the view, i would have to go through the ObjectFactory.Value property. I really wanted to have variables of the type of the views. So I created the AddInitializationMethod, where you can add a lambda expression that will set the member variable for the views. The ActiveAwareUseCaseController will call these lambda’s just before the UseCase becomes active for the first time.

The following code snippet shows how this works in the MainEmailUseCase

   1: // The references to these viewmodels will be filled when the app is initialized for the first time. 
   2: private EmailMainViewModel emailViewModel;
   3: private EmailToolBarViewModel emailToolBarViewModel;
   4:  
   5: public EmailMainUseCase(
   6:     // Get the ViewToRegionBinder that the baseclass needs
   7:     IViewToRegionBinder viewtoToRegionBinder
   8:     // Get the factories that can create the viewmodels
   9:     , ObjectFactory<EmailMainViewModel> emailViewFactory
  10:     , ObjectFactory<EmailToolBarViewModel> emailToolBarFactory) : base(viewtoToRegionBinder)
  11: {
  12:     // Just before the view is initialized for the first time
  13:     this.AddInitializationMethods(
  14:             // Create the emailViewModel and assign it to this variable
  15:         () => this.emailViewModel = emailViewFactory.CreateInstance()
  16:             // Create the toolbarViewModel and assign it to this variable
  17:         , () => this.emailToolBarViewModel = emailToolBarFactory.CreateInstance());
  18: }

Why do I like Constructor Injection? It expresses very clearly what the dependencies of my object are, in a single place.  Take the previous code snippet. You can clearly see that the EmailUseCase has a dependency on the IViewToRegionBinder, the EmailMainViewModel and the EmailToolBarViewModel. Those are the only objects this class interacts with. Sure, in some cases it might seem easier to get a reference to the service locator and resolve types when you need them, but that makes it very unclear what other types your class depends on and also makes unit testing a lot harder.

 

Bootstrapper

As usual, the bootstrapper is the glue for all the individual pieces. In the bootstrapper, all the infrastructure pieces are registered in the right way, so the application can use them. You can see that I’m registering the types i need to the container and some of the default regionbehaviors to the RegionBehaviorFactory

 

What’s next?

In the Outlook style application, i’m also showing a bunch of other things:

  • How to do ViewModel First development in an elegant way.
  • How to use RegionContext in a bit easier way
  • How to show views in a popup in a robust way. Note, in the current version, this is still work in progress.

Since I’ve already spent way to much time on this blogpost, i’m going to address these things in future posts.

As always, I really appreciate your feedback. Any comments or questions are more than welcome.

Happy coding!

_Erwin

[Update: Also read part 2 of this post. ]

I’m really happy and extremely proud to say that we have launched the Prism V2 (the Composite Application Guidance for WPF and Silverlight)

What is prism V2?

Prism is a set of guidance and reusable components that help you create composite applications in WPF and / or Silverlight.  

Prism consists of:

  • Reusable library components, for both WPF and Silverlight.
  • All source code, Unit tests, Automated acceptance tests.
  • Hands on labs (26) that guide you through all aspects of creating a composite application.
  • Quickstarts (9) that illustrate all components of prism.
  • A completely functional reference implementation that shows you how to build a composite application.
  • A lot of documentation and guidance:
    • How to create composite applications
    • How to use the Prism libraries
    • How to use Dependency Injection in your application (Unity)
    • How to create applications that target both WPF and Sliverlight.
    • Which design patterns were used to create prism
    • How to use separated presentation patterns (like Model – View – Viewmodel) to test your UI logic
    • And much, much more.
  • Api Reference documentation
  • A Visual Studio Plugin that helps you to target both WPF and Silverlight with a single codebase. 

When should you consider using Prism V2?

You should consider using prism:

  • If you want to create modular applications, in WPF and / or Silverlight so you can Develop, Test, Version and Deploy your modules independently of each other.
  • If you want to create an application that targets both WPF and Silverlight with a single codebase, or at least reuse a lot of code assets between WPF and Sliverlight.
  • If you want to minimize initial download size Silverlight applications. Prism allows you to just download the minimum of functionality you need to start your application. Other modules can be downloaded on a background thread or on demand.
  • If you are interested in using separated presentation patterns, because you want to create Unit Tests for your UI logic or if you want to make it easier to reskin your application.
  • If you think Prism is Cool :) We certainly do!

What has changed?

A lot of people are using the Composite Application Block for .Net and the Smart Client Software Factory. Although these components definitely addressed the problem space, a lot of people found it complex, hard to use and very heavyweight. It also only targeted windows forms. Also, the So when we created Prism V1, we wanted to take advantage of the power of WPf. We also took a very minimalistic approach and tried very hard to make it a lot easier to use.

If you are interested in the differences between the Composite application block and Prism V1, check this document:

http://msdn.microsoft.com/en-us/library/dd458940.aspx

For Prism V2, most of the changes have revolved around supporting Silverlight with the same codebase. Check this document if you are currently using Prism V1 and are considering upgrading:

http://msdn.microsoft.com/en-us/library/dd490816.aspx

 

Where can you find prism V2?

Prism V2 on MSDN:

http://msdn.microsoft.com/en-us/library/dd458809.aspx

Prism V2 on Codeplex:

http://www.codeplex.com/compositewpf

You can download Prism V2 from:

http://www.microsoft.com/downloads/details.aspx?FamilyID=fa07e1ce-ca3f-4b9b-a21b-e3fa10d013dd&DisplayLang=en

And the CHM help files:

http://www.codeplex.com/CompositeWPF/Release/ProjectReleases.aspx?ReleaseId=14982

 

Feedback

All feedback on Prism is welcome. Really! We need feedback from the community to ensure we build the stuff you need!

  • If you are using Prism and you don’t like it (or parts of it), let us know, so we can address those issues in future versions.
  • If you are experiencing difficulties, let us know! Post a question on the forums on Codeplex (http://www.codeplex.com/CompositeWPF/Thread/List.aspx, or send me a message through my blog). We will be actively monitoring the forums and if we can, we will help!
  • Hopefully, you are using Prism and you like it. If so, we also love to know! What kind of application are you using Prism for? And of course, Let us know the features you really liked, so we don’t cut your favorite feature in a future version!

Hope you like Prism V2 as much as we enjoyed building it.

_Erwin

While writing some sample applications for the upcoming release of Prism (Composite Application Guidance for WPF and Silverlight) I ran into a small challenge.

“How do you verify (with unit tests) that the right classes are registered in your DI-container?”

In my case, the container is Unity, but Unity does not have any ‘IsTypeRegistered’ methods (Apparently there are good reasons for it not to have these methods). So that posses an interesting challenge. At first I thought of 2 solutions:

  • Manually create a mock of your container.
    Certainly possible but a lot of work for my small demo app. A mocking framework can help with this, but i don’t want to rely on a mocking framework for a small demo app.
  • See if the components are registered by resolving the type.
    This will work initially, but it will actually instantiate the object. So if the object can’t be created for some reason, your test will fail. Now if the type you have just registered has a lot of dependencies, you will need to satisfy all those dependencies in the container before you can even begin to create the object.

But neither of these options were really satisfying. Then I asked Chris Tavarez, and he mentioned: Why don’t you build a Unity Extension. So I did and that solved the problem quite nicely:

So this is the Extension I’ve created:

   1: public class QueryableContainerExtension : UnityContainerExtension
   2: {
   3:     public List<RegisterEventArgs> Registrations = new List<RegisterEventArgs>();
   4:  
   5:     protected override void Initialize()
   6:     {
   7:         this.Context.Registering += new EventHandler<RegisterEventArgs>(Context_Registering);
   8:     }
   9:  
  10:     void Context_Registering(object sender, RegisterEventArgs e)
  11:     {
  12:         this.Registrations.Add(e);
  13:     }
  14:  
  15:     public bool IsTypeRegistered<TFrom, TTo>()
  16:     {
  17:         return this.Registrations.FirstOrDefault((e) => e.TypeFrom == typeof(TFrom) && e.TypeTo == typeof(TTo)) != null;
  18:     }
  19:  
  20:     public bool IsTypeRegisteredAsSingleton<TFrom, TTo>()
  21:     {
  22:         return this.Registrations.FirstOrDefault(
  23:             (e) => e.TypeFrom == typeof(TFrom)
  24:                 && e.TypeTo == typeof(TTo)
  25:                 && typeof(ContainerControlledLifetimeManager).IsInstanceOfType(e.LifetimeManager)) != null;
  26:     }
  27: }

 

And this is how you’d use it:

   1: [TestMethod]
   2: public void TestRegistration()
   3: {
   4:     // Create the container and add the extension method
   5:     var container = new UnityContainer();
   6:     var registeredTypes = new QueryableContainerExtension();
   7:     container.AddExtension(registeredTypes);
   8:  
   9:     // Register the classes to the container
  10:     container.Register<IMyInterface, MyClass>();
  11:  
  12:     // See if the type is registered
  13:     Assert.IsTrue(registeredTypes.IsTypeRegistered<IMyInterface, MyClass>());
  14: }

Hope you find this as useful as I did :)

More Posts Next page »
 
Page view tracker