This project is read-only.

How To: Enable CWAB in a SharePoint Application

The objective of enabling the Composite Web Application Block in a SharePoint application is allowing it to use all its features like separation of concerns, reusability and dependency injection.

Separation of concerns allows developers to use CWAB features to develop Web applications that are composed of independent, but collaborating, modules. This allows developers or teams to concentrate on specific tasks.
Extensibility is promoted by the Composite Web Application Block in many different ways. With it, you can replace the behaviors and strategies provided as defaults with your own implementations and add custom services and behaviors.
Dependency Injection in CWAB is performed by using a composition container to hold different elements of your application. These elements are injected into your classes when necessary allowing your classes to be decoupled, because there are no hard references between them. Therefore you can unit test your application’s functionality in isolation.
To improve the testing capabilities of the presentation layer, the MVP (Model View Presenter) pattern is used in this example. There are different implementations of this pattern, but its main goal is to locate all the “complex” logic to update the User Interface in a presenter class, which makes your views easier to test.
This guidance describes how to enable CWAB in a SharePoint application and how to test a sample Web Part using the MVP pattern.

You can download it from here.

Contents

Material

This guidance includes extensions to enable the Composite Web Application Block on a SharePoint application: the CompositeWeb.Sharepoint.dll assembly. This assembly is required to implement the proposed solution.
The CompositeWeb.Sharepoint assembly contains the following classes:
  • CompositeWeb.SharePoint.SPWebClientApplication: a custom implementation of the IWebClientApplication interface that inherits from SPHttpApplication.
  • CompositeWeb.SharePoint.RootContainerLocatorService: a custom implementation of the IModuleContainerLocatorService interface that always returns the root container to avoid business modules incompatibilities in SharePoint applications.
  • CompositeWeb.SharePoint.Web.UI.UserControl: a base class to make user controls support CWAB dependency injection in SharePoint and WCSF applications.
  • CompositeWeb.SharePoint.Web.UI.WebPart: a base class to make web parts support CWAB dependency injection in SharePoint and WCSF applications.
To perform all the tasks on this guidance, you will use the CWABSharePoint.sln base solution. This solution is configured to use the Composite Web extensions for SharePoint, and it contains: You can download the guidance from here.

CwabSolution.png

How To: Enable CWAB in a SharePoint Application

Applications developed with the Web Client Software Factory use a set of infrastructure elements that include Services, Http Modules, Containers, configuration files, and other components that combined provide a framework –the Composite Web Application Block - to facilitate the development of composite Web client solutions. This set of interrelated elements enables Web client developers to use features such as the Dependency Injection mechanism, the module site map provider, or automated authorization checks for Web pages.
SharePoint developers can build custom Web Parts that are hosted inside SharePoint applications. This enables SharePoint developers to build rich SharePoint views that take advantage of the SharePoint infrastructure together with custom logic.
By default, SharePoint applications do not provide out-of-the-box configuration to allow developers to take advantage of the features provided by the Composite Web Application Block. However, through a series of steps, developers can enable SharePoint applications to support some of the features provided by the Composite Web Application Block, including dependency injection.
The Composite Web Application Block includes a custom global application class, the WebClientApplication class, whose main responsibilities include initialization of the containers, module loading, and infrastructure services set up.
This How-To topic describes the steps required to enable the Composite Web Application Block in SharePoint applications.
  • 1. Open the CompositeWeb.SharePoint.sln solution file and build it.
  • 2. Copy the CompositeWeb.SharePoint.dll assembly from the Debug folder of the solution to the Bin folder of the SharePoint application. This folder is usually located at C:\Inetpub\wwwroot\wss\VirtualDirectories\{sharepoint application}\Bin.
  • 3. Open the Global.asax file of your SharePoint application (typically located in the folder C:\Inetpub\wwwroot\wss\VirtualDirectories\{sharepoint application}), and replace its content with the following code.
<%@ Application Language="C#" Inherits="CompositeWeb.SharePoint.SPWebClientApplication" %>
* 4. Save the file and close it.
  • 5. Open the Web.Config file located in the root folder of your SharePoint application and add the following configuration section definitions:
<configuration>
    <configSections>
    ...
        <sectionGroup name="compositeWeb">
            <section name="modules" 
			type="Microsoft.Practices.CompositeWeb.Configuration.ModulesConfigurationSection, 
			Microsoft.Practices.CompositeWeb"/>
        </sectionGroup>
    </configSections>
    ...
</configuration>
* 6. Add the following configuration sections under the configuration element to configure the Foundational modules your application will use:
<configuration>
    ...
    <compositeWeb>
        <modules>
            <module name="..." assemblyName="..." />
        </modules>
    </compositeWeb>
    ...
<configuration>
* 7. Find the trust element under system.web element and set it to Full (this is required by CWAB assemblies to work).
<trust level="Full" originUrl="" />
* 8. Save the file and close it.
Note:Enterprise Library configuration was not included in the Web.Config file for simplicity reasons and because SharePoint applications already provide services like authentication and authorization. However, you can add these configurations if you want to use Enterprise Library application blocks in your application.

The SharePoint Web Parts you build to be used with CWAB dependency injection need to inherit from the CompositeWeb.SharePoint.Web.UI.WebPart base class.

How To: Reuse WCSF User Controls in SharePoint

The Composite Web Application Block extensions for SharePoint (see the Material topic) allow Web Parts to work both in WCSF and SharePoint applications. Developers will be able to migrate User Controls between their applications without having to change any code or configuration.
This is achieved through the BuildItemWithCurrentContext method in the SPWebClientApplication class. This method runs different code depending on the running HttpApplication implementation.
See the following code snippets:
  • The CompositeWeb.SharePoint.SPWebClientApplication class:
public static void BuildItemWithCurrentContext(object obj)
{
    IHttpContext context = CurrentContext;
    if (context.ApplicationInstance is SPWebClientApplication)
    {
        SPWebClientApplication app = (SPWebClientApplication)context.ApplicationInstance;
        Ibuilder<WCSFBuilderStage> builder = app.PageBuilder;
        CompositionContainer container = app.GetModuleContainer(context);
        CompositionContainer.BuildItem(builder, container.Locator, obj);
    }
    else if (context.ApplicationInstance is WebClientApplication)
    {
        WebClientApplication.BuildItemWithCurrentContext(obj);
    }
}
* The CompositeWeb.SharePoint.Web.UI.WebPart class:
namespace CompositeWeb.SharePoint.Web.UI
{
    public class WebPart : System.Web.UI.WebControls.WebParts.WebPart
    {
        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
            SPWebClientApplication.BuildItemWithCurrentContext(this);
        }
    }
}

How To: Use CWAB to Build Testable SharePoint Web Parts

In this task, you will create a new Web Part implementing the Model-View-Presenter pattern to make it more testable (the Composite Web Application Block allows you to implement this pattern in a loosely coupled fashion by using Dependency Injection). You will then unit test the presenter class and host the Web Part in the SharePoint solution.
This can be easily achieved given that, as explained in the introduction of this document, your web parts and services can be mocked, allowing you to concentrate only in the presenter’s logic. The mocks will be obtained by implementing the interfaces, for both the Web Part and Service classes.

Create a Web Part implementing the MVP pattern

The following procedure explains how to programmatically create a Web Part that is injected with its presenter. As stated in the introduction of this document, this separates the responsibilities of the Web Part and its Presenter making it easier to test.
  • 1. Open the initial CWABSharePoint.sln solution.
  • 2. Add an Interface named ISimpleWebPart in the root of the CustomWebParts project with the following code:
public interface ISimpleWebPart
{
    string Message { get; set; }
    string Name { get; set; }
}
* 3. Add a class named SimpleWebPartPresenter in the root of the CustomWebParts project with the following code:
public class SimpleWebPartPresenter : Presenter<ISimpleWebPart>
{
    public void OnSayHello()
    {
        View.Message = GetGreetingsMessage();
    }

    private string GetGreetingsMessage()
    {
        return string.Format("Hello, {0}!", View.Name);
    }
}
* 4. Add a new folder named SimpleWebPart to the CustomWebParts project.
  • 5. Create a Web Part named SimpleWebPart in the previously created folder.
Note: You can also use the SharePoint templates to create your Web Parts if you have them installed.
  • 6. Modify the SimpleWebPart class definition to extend the CompositeWeb.SharePoint.Web.UI.WebPart class and implement the ISimpleWebPart interface:
public class SimpleWebPart :
CompositeWeb.SharePoint.Web.UI.WebPart, ISimpleWebPart
* 7. Implement the method of the ISimpleWebPart interface in this way:
Label lblMessage;

public string Message
{
    get { return lblMessage.Text; }
    set { lblMessage.Text = value; }
}

public string Name { get; set; }
* 8. Paste the following code inside the SimpleWebPart class to inject the SimpleWebPartPresenter presenter:
SimpleWebPartPresenter presenter;

[CreateNew]
public SimpleWebPartPresenter Presenter 
{
    get { return presenter; }
    set { 
        presenter = value;
        presenter.View = this;
    } 
}
* 9. Add a button named btnSayHello to the SimpleWebPart web part with the following handler for the Click event:
public void btnSayHello_Click(object sender, EventArgs e)
{
    this.Name = "Web Part";
    Presenter.OnSayHello();
}
* 10. Override the Render method of the SimpleWebPart web part with the following code:
protected override void Render(HtmlTextWriter writer)
{
    btnSayHello.RenderControl(writer);
    
    writer.WriteLine("<br/><strong>");
    lblMessage.RenderControl(writer);
    writer.Write("</strong>");
}
* 11. Build the solution.

Unit Test the presenter

When you implement the Model-View-Presenter pattern, you can test the presenter independently of the view and model “real” implementations by creating mock implementations of the view and model. This helps you focus on the presenter’s logic and eliminates dependencies that might not be appropriate for testing environments.
To test the presenter more easily, we will create a MockWebPart implementing the ISimpleWebPart interface. The same approach can be applied to any model objects that the presenter requires.
  • 1. Add a new Test Project named CustomWebParts.Tests to the CWABSharePoint solution.
  • 2. Create a MockSimpleWebPart class in the CustomWebParts.Test project that implements the ISimpleWebPart interface.
public class MockSimpleWebPart : ISimpleWebPart
{
    public bool MessageCalled = false;
    public bool NameCalled = false;
    
    public string Message
    {
        get
        {
            MessageCalled = true;
            return "Hello";
        }
        set { MessageCalled = true; }
    }

    public string Name
    {
        get
        {
            NameCalled = true;
            return "John Doe";
        }
        set { NameCalled = true; }
    }
}
* 3. Create a Test Class named SimpleWebPartPresenterTestFixture in the CustomWebParts.Test project with the following code:
[TestClass()]
public class SimpleWebPartPresenterTestFixture
{
    private MockSimpleWebPart _view;

    [TestMethod()]
    public void OnSayHelloTest()
    {
        SimpleWebPartPresenter presenter = GetSimpleWebPartPresenter();

        presenter.OnSayHello();

        Assert.IsTrue(_view.MessageCalled);
        Assert.IsTrue(_view.NameCalled);
    }

    private SimpleWebPartPresenter GetSimpleWebPartPresenter()
    {
        _view = new MockSimpleWebPart();

        SimpleWebPartPresenter presenter = new SimpleWebPartPresenter();
        presenter.View = _view;

        return presenter;
    }
}
* 4. Compile and run the tests. They should pass.

Deploy the Web Part to the SharePoint solution

In this task you will deploy the WebPart created in the previous task to your SharePoint solution.
  • 1. Open the Web.config file of your SharePoint application (see How To: Enable CWAB in a SharePoint Application).
  • 2. Find out the PublicKeyToken of your CustomWebParts project. You can use the command “sn.exe -T CustomWebParts.dll” to get it.
  • 3. Add the following line under the configuration/SharePoint/SafeControl element and set the PublicKeyToken and Namespace attributes to these correct values.
<SafeControl Assembly="CustomWebParts, Version=1.0.0.0, Culture=neutral, PublicKeyToken=dec9f63286a99908" 
Namespace="CustomWebParts.SimpleWebPart" TypeName="*" Safe="True" AllowRemoteDesigner="True" />
* 4. Save the file and close it.
  • 5. Copy the file CustomWebParts.dll and its dependencies (if any) to the bin folder of the SharePoint application usually located at: C:\Inetpub\wwwroot\wss\VirtualDirectories\{sharepoint application}\bin.
  • 6. Open, in a browser, the SharePoint web site to set up the Web Part.
  • 7. Go to Site Actions | Site Settings.
siteActions.png
  • 8. Click on Galleries – Web Parts link.
Gallery.png
  • 9. Click on New button.
WebPartGallery.png
  • 10. Find and check your Web Part (CustomWebParts.SimpleWebPart.SimpleWebPart) and click on Populate Gallery button.
SimpleWebPart.png
  • 11. In the Web Part Gallery, find your Web Part (it has a “!New” icon).
new.png

How To: Reuse Foundational Modules in SharePoint

Composite Web applications usually have modules which are units of development and deployment that encapsulate infrastructure services. This type of module is known as a Foundational Module. The goal of Foundational Modules is enabling certain functionality for the entire application by adding the service to the container, which will inject it in your different objects.
In this task, you will inject a service defined in a Foundational Module, created with WCSF – February 2008, in the SimpleWebPartPresenter.
  • 1. Open the CWABSharePoint.sln solution.
  • 2. In the CustomWebParts project, add a project reference to the Services.Interface project.
  • 3. Add the following code inside the SimpleWebPartPresenter class to inject the ISampleService service:
[ServiceDependency]
public ISampleService Service
{ get; set; }
* 4. In the SimpleWebPartPresenter class, replace the GetGreetingsMessage method with the following one:
private string GetGreetingsMessage()
{
    return string.Format("Hello, {0}!", string.Format(Service.GetMessage(), View.Name));
}
This method uses the service to retrieve a message.
  • 5. Build the solution.
Note: Having changed the presenter’s implementation the tests created in the Unit Test the presenter topic will fail.

Deploy the updated Web Part to the SharePoint solution {anchro:DeployWP2}

This task will guide you through the steps of deploying the updated Web Part to your SharePoint solution.
  • 1. Open the Web.config file of your SharePoint application (see How To: Enable CWAB in a SharePoint Application).
  • 2. In the CompositeWeb configuration section, add the following tag:
<compositeWeb>
	<modules>
		<module name="Services" assemblyName="Services"/>
	</modules>
</compositeWeb>
* 3. Copy the following assemblies to the Bin folder of the SharePoint application (usually located at: C:\Inetpub\wwwroot\wss\VirtualDirectories\{sharepoint application}\bin):
  • CustomWebParts.dll
  • Services.dll
  • Services.Interface.dll
  • 4. Click the Say Hello button of the SimpleWebPart to see how it works.
SimpleWebPart-working.png

Outcome

After performing all tasks in this document you have:
  • Enabled the Composite Web Application Block in your SharePoint application.
  • Implemented the MVP pattern in a Web Part.
  • Registered and used a service that was injected in your presenter class.
  • Created a unit test for your presenter class.

Last edited Sep 8, 2008 at 9:45 PM by mconverti, version 3

Comments

kurengan May 28, 2009 at 2:46 PM 
A nice article and guidline step wise step to work on. But the btnSayHello.Click += new EventHandler(btnSayHello_Click); is not working. When the button is clicked the listner btnSayHello_Click is not getting called. Is it required to change the config? Or something is missing. Presenter.OnSayHello(); is getting called when placed in the method CreateChildControls() but not from the event listener.