Maarten Balliauw {blog}

ASP.NET, ASP.NET MVC, Windows Azure, PHP, ...

NAVIGATION - SEARCH

PHP Managed Extensibility Framework – PHPMEF

image While flying sitting in the airplane to the Microsoft Web Developer Summit in Seattle, I was watching some PDC09 sessions on my laptop. During the MEF session, an idea popped up: there is no MEF for PHP! 3500 kilometers after that moment, PHP got its own MEF…

What is MEF about?

MEF is a .NET library, targeting extensibility of projects. It allows you to declaratively extend your application instead of requiring you to do a lot of plumbing. All this is done with three concepts in mind: export, import and compose. (Glenn, I stole the previous sentence from your blog). “PHPMEF” uses the same concepts in order to provide this extensibility features.

Let’s start with a story… Imagine you are building a Calculator. Yes, shoot me, this is not a sexy sample. Remember I wrote this one a plane with snoring people next to me…The Calculator is built of zero or more ICalculationFunction instances. Think command pattern. Here’s how such an interface can look like:

[code:c#]

interface ICalculationFunction
{
    public function execute($a, $b);
}

[/code]

Nothing special yet. Now let’s implement an instance which does sums:

[code:c#]

class Sum implements ICalculationFunction
{
    public function execute($a, $b)
    {
        return $a + $b;
    }
}

[/code]

Now how would you go about using this in the following Calculator class:

[code:c#]

class Calculator
{
    public $CalculationFunctions;
}

[/code]

Yes, you would do plumbing. Either instantiating the Sum object and adding it into the Calculator constructor, or something similar. Imagine you also have a Division object. And other calculation functions. How would you go about building this in a maintainable and extensible way? Easy: use exports…

Export

Exports are one of the three fundaments of PHPMEF. Basically, you can specify that you want class X to be “ exported”  for extensibility. Let’s export Sum:

[code:c#]

/**
  * @export ICalculationFunction
  */
class Sum implements ICalculationFunction
{
    public function execute($a, $b)
    {
        return $a + $b;
    }
}

[/code]

Sum is exported as Sum by default, but in this case I want PHPMEF to know that it is also exported as ICalculationFunction. Let’s see why this is in the import part…

Import

Import is a concept required for PHPMEF to know where to instantiate specific objects. Here’s an example:

[code:c#]

class Calculator
{
    /**
      * @import ICalculationFunction
      */
    public $SomeFunction;
}

[/code]

In this case, PHPMEF will simply instantiate the first ICalculationFunction instance it can find and assign it to the Calculator::SomeFunction variable. Now think of our first example: we want different calculation functions in our calculator! Here’s how:

[code:c#]

class Calculator
{
    /**
      *  @import-many ICalculationFunction
      */
    public $CalculationFunctions;
}

[/code]

Easy, no? PHPMEF will ensure that all possible ICalculationFunction instances are added to the Calculator::CalculationFunctions array. Now how is all this being plumbed together? It’s not plumbed! It’s composed!

Compose

Composing matches all exports and imports in a specific application path. How? Easy! Use the PartInitializer!

[code:c#]

// Create new Calculator instance
$calculator = new Calculator();

// Satisfy dynamic imports
$partInitializer = new Microsoft_MEF_PartInitializer();
$partInitializer->satisfyImports($calculator);

[/code]

Easy, no? Ask the PartInitializer to satisfy all imports and you are done!

Advanced usage scenarios

The above sample was used to demonstrate what PHPMEF is all about. I’m sure you can imagine more complex scenarios. Here are some other possibilities…

Single instance exports

By default, PHPMEF instantiates a new object every time an import has to be satisfied. However, imagine you want our Sum class to be re-used. You want PHPMEF to assign the same instance over and over again, no matter where and how much it is being imported. Again, no plumbing. Just add a declarative comment:

[code:c#]

/**
  * @export ICalculationFunction
  * @export-metadata singleinstance
  */
class Sum implements ICalculationFunction
{
    public function execute($a, $b)
    {
        return $a + $b;
    }
}

[/code]

Export/import metadata

Imagine you want to work with interfaces like mentioned above, but want to use a specific implementation that has certain metadata defined. Again: easy and no plumbing!

My calculator might look like the following:

[code:c#]

class Calculator
{
    /**
      *  @import-many ICalculationFunction
      */
    public $CalculationFunctions;

    /**
      *  @import ICalculationFunction
      *  @import-metadata CanDoSums
      */
    public $SomethingThatCanDoSums;
}

[/code]

Calculator::SomeThingThatCanDoSums is now constrained: I only want to import something that has the metadata “CanDoSums” attached. Here’s how to create such an export:

[code:c#]

/**
  * @export ICalculationFunction
  * @export-metadata CanDoSums
  */
class Sum implements ICalculationFunction
{
    public function execute($a, $b)
    {
        return $a + $b;
    }
}

[/code]

Here’s an answer to a question you may have: yes, multiple metadata definitions are possible and will be used to determine if an export matches an import.

One small note left: you can also ask the PartInitializer for the metadata defined on a class.

[code:c#]

// Create new Calculator instance
$calculator = new Calculator();

// Satisfy dynamic imports
$partInitializer = new Microsoft_MEF_PartInitializer();
$partInitializer->satisfyImports($calculator);

// Get metadata
$metadata = $partInitializer->getMetadataForClass('Sum');

[/code]

Can I get the source?

No, not yet. For a number of reasons. I first want to make this thing a bit more stable, as well as deciding if all MEF features should be ported. Also, I’m looking for an appropriate name/library to put this in. You may have noticed the Microsoft_* naming, a small hint to the Interop team in incorporating this as another Microsoft library in the PHP world. Yes Vijay, talking to you :-)

Supporting multiple submit buttons on an ASP.NET MVC view

Multiple buttons on an ASP.NET MVC view A while ago, I was asked for advice on how to support multiple submit buttons in an ASP.NET MVC application, preferably without using any JavaScript. The idea was that a form could contain more than one submit button issuing a form post to a different controller action.

The above situation can be solved in many ways, one a bit cleaner than the other. For example, one could post the form back to one action method and determine which method should be called from that action method. Good solution, however: not standardized within a project and just not that maintainable… A better solution in this case was to create an ActionNameSelectorAttribute.

Whenever you decorate an action method in a controller with the ActionNameSelectorAttribute (or a subclass), ASP.NET MVC will use this attribute to determine which action method to call. For example, one of the ASP.NET MVC ActionNameSelectorAttribute subclasses is the ActionNameAttribute. Guess what the action name for the following code snippet will be for ASP.NET MVC:

[code:c#]

public class HomeController : Controller
{
    [ActionName("Index")]
    public ActionResult Abcdefghij()
    {
        return View();
    }
}

[/code]

That’s correct: this action method will be called Index instead of Abcdefghij. What happens at runtime is that ASP.NET MVC checks the ActionNameAttribute and asks if it applies for a specific request. Now let’s see if we can use this behavior for our multiple submit button scenario.

kick it on DotNetKicks.com

The view

Since our view should not be aware of the server-side plumbing, we can simply create a view that looks like this.

[code:c#]

<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<MvcMultiButton.Models.Person>" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>Create person</title>
    <script src="<%=Url.Content("~/Scripts/MicrosoftAjax.js")%>" type="text/javascript"></script>
    <script src="<%=Url.Content("~/Scripts/MicrosoftMvcAjax.js")%>" type="text/javascript"></script>
</head>
<body>

    <% Html.EnableClientValidation(); %>
    <% using (Html.BeginForm()) {%>

        <fieldset>
            <legend>Create person</legend>
            <p>
                <%= Html.LabelFor(model => model.Name) %>
                <%= Html.TextBoxFor(model => model.Name) %>
                <%= Html.ValidationMessageFor(model => model.Name) %>
            </p>
            <p>
                <%= Html.LabelFor(model => model.Email) %>
                <%= Html.TextBoxFor(model => model.Email) %>
                <%= Html.ValidationMessageFor(model => model.Email) %>
            </p>
            <p>
                <input type="submit" value="Cancel" name="action" />
                <input type="submit" value="Create" name="action" />
            </p>
        </fieldset>

    <% } %>

    <div>
        <%=Html.ActionLink("Back to List", "Index") %>
    </div>

</body>
</html>

[/code]

Note the two submit buttons (namely “Cancel” and “Create”), both named “action” but with a different value attribute.

The controller

Our controller should also not contain too much logic for determining the correct action method to be called. Here’s what I propose:

[code:c#]

public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View(new Person());
    }

    [HttpPost]
    [MultiButton(MatchFormKey="action", MatchFormValue="Cancel")]
    public ActionResult Cancel()
    {
        return Content("Cancel clicked");
    }

    [HttpPost]
    [MultiButton(MatchFormKey = "action", MatchFormValue = "Create")]
    public ActionResult Create(Person person)
    {
        return Content("Create clicked");
    }
}

[/code]

Some things to note:

  • There’s the Index action method which just renders the view described previously.
  • There’s a Cancel action method which will trigger when clicking the Cancel button.
  • There’s a Create action method which will trigger when clicking the Create button.

Now how do these last two work… You may also have noticed the MultiButtonAttribute being applied. We’ll see the implementation in a minute. In short, this is a subclass for the ActionNameSelectorAttribute, triggering on the parameters MatchFormKey and MatchFormValues. Now let’s see how the MultiButtonAttribute class is built…

The MultiButtonAttribute class

Now do be surprised of the amount of code that is coming…

[code:c#]

[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class MultiButtonAttribute : ActionNameSelectorAttribute
{
    public string MatchFormKey { get; set; }
    public string MatchFormValue { get; set; }

    public override bool IsValidName(ControllerContext controllerContext, string actionName, MethodInfo methodInfo)
    {
        return controllerContext.HttpContext.Request[MatchFormKey] != null &&
            controllerContext.HttpContext.Request[MatchFormKey] == MatchFormValue;
    }
}

[/code]

When applying the MultiButtonAttribute to an action method, ASP.NET MVC will come and call the IsValidName method. Next, we just check if the MatchFormKey value is one of the request keys, and the MatchFormValue matches the value in the request. Simple, straightforward and re-usable.

kick it on DotNetKicks.com

Book review: Zend Framework 1.8 Web Application Development

Zend Framework 1.8 Web Application Development My book shelf is starting to look a lot like the warehouse of Packt Publishing: I’ve received yet another book from them. Different from all previous reviews I did: this one is a PHP book, titled “Zend Framework 1.8 Web Application Development” by Keith Pope.

A chapter overview:

  • Chapter 1: Creating a Basic MVC Application
  • Chapter 2: The Zend Framework MVC Architecture
  • Chapter 3: Storefront Basic Setup
  • Chapter 4: Storefront Models (great chapter!)
  • Chapter 5: Implementing the Catalog
  • Chapter 6: Implementing User Accounts
  • Chapter 7: The Shopping Cart
  • Chapter 8: Authentication and Authorization
  • Chapter 9: The Administration Area
  • Chapter 10: Storefront Roundup
  • Chapter 11: Storefront Optimization
  • Chapter 12: Testing the Storefront

Let’s also state the obvious: Zend Framework evolves much faster than publishers. The framework is now at 1.9.6, while the book covers 1.8.0. Do not let this stop you from reading this book! Let me explain why…

  1. The book covers all concepts and components in the Zend Framework in a full-blown application that is built up from scratch.
  2. Next to that, Keith Pope focuses a lot on the application design, using interfaces, unit testing, mocking, dependency injection, … Want to learn a lot about good application design? Then this is the number one reason to read this book!

These 2 points actually summarize the whole book. Great read, great content and a must-read for everyone who is not completely sure about his application design skills. Congratulations, Keith!

MSDN - Converting an existing ASP.NET application to Windows Azure

Back from PDC 2009 with a lot of information on Windows Azure, I did an MSDN Live Meeting on ASP.NET and Windows Azure today. Here's the slide deck and demo code.

Abstract: "Put your stuff in the cloud! Windows Azure allows you to take advantage of cloud computing infranstructure for hosting, computing, and storage of your applications. In this demo filled session we take an existing ASP.Net Application and move it to be hosted in Windows Azure, while taking advantage of Windows Azure storage."

Example code can be downloaded here: MSDN - Converting an existing ASP.NET application to Windows Azure.zip (2.01 mb)

If you want more info about Windows Azure and how to develop, architect or benefit from the platform as a whole, register freely at the Azure User Group Belgium.

Before you get started, you need to have a Windows Azure token. Request a token by completing the application here. Tokens are generally issued within a few hours. Once you have received your token, redeem it at http://windows.azure.com. Afterwards, you can deploy your application using the interface at http://windows.azure.com or by issuing a right-click -> Publish... in your Visual Studio solution.

Windos Azure Developer Portal

Thank you for attending!

kick it on DotNetKicks.com

Microsoft PDC09 day 2 keynote highlights

Happiness, pure happiness!

Day 2 keynote at Microsoft PDC 2009 was quite exciting. To sum things up: Silverlight 4 went beta, IE9 features were previewed, and we got an external hard disk, nicely fitted in a tablet-pc format case. How thoughtful!

Here’s some of the novelties:

Silverlight 4 Beta

This was a good starter… It’s really incredibly feature packed! In my opinion, I think WCF can now be called obsolete as well, but no announcements on that :-) Anyway, here’s a list of new features: webcam access, multicast streaming, offline DRM and output protection, printing, clipboard support, out-of-browser and out-of-sandbox support, drag and drop, implicit styling, a HTML control, rich-text editing, breathe, ability to share assemblies with .NET 4, data binding improvements, udp multicast, REST enhancements, TCP channel support, …

Also check Tim Heuer’s blog post over at http://timheuer.com/blog/archive/2009/11/18/whats-new-in-silverlight-4-complete-guide-new-features.aspx.

IE9

Yes, IE9 was announced. Running JavaScript lots faster, passing more of the ACID3 test (still not all), and the coolest part: Direct3D rendering of all graphic content. This was demoed and approved by the audience: everything is so muh faster and smoother!

WCF RIA Services

Check out Brad Abrams’ blog for this: http://blogs.msdn.com/brada/archive/2009/11/18/welcome-to-wcf-ria-services-beta.aspx

Basically a rename of RIA services, and converted to run on top of WCF rather than an own transport layer implementation in previous versions.

Overall: a great PDC09 day two!

Microsoft PDC09 keynote highlights

Finally found some time to write a short blog post on the announcements this morning at PDC 2009.Microsoft PDC keynote highlights Ray Ozzie started the keynote this morning, focusing on Microsoft’s “three-screen” vision for the future. There will be three screens connected to the cloud: TV, (handheld) devices and of course good old PC. This vision is driven by some key players: Windows 7, Internet Explorer, Silverlight and Windows Azure. Make sure to have a look at these four if you want to play in this future.

Some announcements were made as well:

Had a great day yesterday, driving trough the city of Los Angeles and looking at various places in town. Conference day one was also very interesting, lots of good sessions. Currently missing a session slot though, waiting for a Channel9 interview on the Windows Azure SDK for PHP. Stay tuned!

Localize ASP.NET MVC 2 DataAnnotations validation messages

Living in a country where there are there are three languages being used, almost every application you work on requires some form of localization. In an earlier blog post, I already mentioned ASP.NET MVC 2’s DataAnnotations support for doing model validation. Ever since, I was wondering if it would be possible to use resource files or something to do localization of error messages, since every example that could be found on the Internet looks something like this:

[code:c#]

[MetadataType(typeof(PersonBuddy))]
public class Person
{
    public string Name { get; set; }
    public string Email { get; set; }
}

public class PersonBuddy
{
    [Required(ErrorMessage = "Name is required.")]
    public string Name { get; set; }

    [Required(ErrorMessage = "E-mail is required.")
    public string Email { get; set; }
}

[/code]

Yes, those are hardcoded error messages. And yes, only in one language. Let’s see how localization of these would work.

1. Create a resource file

Add a resource file to your ASP.NET MVC 2 application. Not in App_GlobalResources or App_LocalResources, just a resource file in a regular namespace. Next, enter all error messages that should be localized in a key/value manner. Before you leave this file, make sure that the Access Modifier property is set to Public.

Access modifier in resource file

2. Update your “buddy classes”

Update your “buddy classes” (or metadata classes or whatever you call them) to use the ErrorMessageResourceType and ErrorMessageResourceName parameters instead of the ErrorMessage parameter that you normally pass. Here’s the example from above:

[code:c#]

[MetadataType(typeof(PersonBuddy))]
public class Person
{
    public string Name { get; set; }
    public string Email { get; set; }
}

public class PersonBuddy
{
    [Required(ErrorMessageResourceType = typeof(Resources.ModelValidation), ErrorMessageResourceName = "NameRequired")]
    public string Name { get; set; }

    [Required(ErrorMessageResourceType = typeof(Resources.ModelValidation), ErrorMessageResourceName = "EmailRequired")]
    public string Email { get; set; }
}

[/code]

3. See it work!

After creating a resource file and updating the buddy classes, you can go back to work and use model binders, ValidationMessage and ValidationSummary. ASP.NET will make sure that the correct language is used based on the thread culture info.

Localized error messages

kick it on DotNetKicks.com

Windows Azure Tools for Eclipse for PHP developers

Pfew! Finally I can spread the word on this! While working on the Windows Azure SDK for PHP, I had the opportunity to test-drive the development builds of the WIndows Azure Tools for Eclipse. Today, the project has been released officially at www.windowsazure4e.org. Windows Azure Tools for Eclipse provides a series of wizards and utilities that allow developers to write, debug, and configure for and deploy PHP applications to Windows Azure.

image

The plug-in also bundles the existing Windows Azure SDK for PHP, which was introduced a few months ago. This SDK provides a simple API for PHP developers who use the Windows Azure storage component, making it very easy to use the blob, queue and table data storage features. Just visit the project site at http://phpazure.codeplex.com/.

Some labs are available to help you get started with PHP on the WIndows Azure platform: http://www.windowsazure4e.org/learn/

Upcoming sessions on Azure, PHP and ASP.NET

It’s going to be a filled end of 2009… There’s Microsoft PDC which I will be attending and will probably cause me some sleepless nights (both due to jetlag and due to all the new stuff that will be released). Next to that, I’ll also be doing some sessions in the next few weeks. Here’s a list…

Date

Event

28 october 2009

PHPBenelux Meeting: PHP and Microsoft technologies

I’ll be doing two sessions here:

· PHP and Silverlight, together with Kevin Dockx
“This session covers the basics of Microsoft Silverlight and demonstrates how PHP developers can benefit from developing rich client-side components that run in the web browser using Silverlight and PHP.”

· Make Web not War, together with Katrien De Graeve
“Microsoft will present the array of initiatives in the company to better support and integrate with PHP and give you an introduction on Windows Azure and its support for PHP in the cloud.”

More info? www.phpbenelux.eu

4 november 2009

First Azure User Group Belgium (AZUG.be) meeting

I’ll be doing an introductory session to Microsoft’s Azure platform. Yves Goeleven and Kurt Claeys will be showing off .NET services and provide more info on the AZUG.be. All of this followed by an open discussion.

Register now on www.azug.be!

24 november 2009

MSDN Live Meeting (Dutch)

Een ASP.NET-applicatie overbrengen naar Windows Azure
“Zet alles over naar the cloud! Met Windows Azure kunt u voordeel halen uit de cloud computing-infrastructuur voor hosting, computing en storage van uw applicaties. De sessie bevat talrijke demo’s, we brengen een bestaande ASP.Net-applicatie over naar hosting in Windows Azure en maken gebruik van Windows Azure storage”

More info on the MSDN pages!

Looking forward to see you at one of these events!

Recording of my session at Remix 2009 - ASP.NET MVC

On September 29, I did a session on ASP.NET MVC at Remix 2009 Belgium. All session recordings are now online, check the Remix09 site. Slides and code for my talk can be found in a previous blog post. The video material can be found below. Enjoy! And feel free to leave some comments!

kick it on DotNetKicks.com

ASP.NET MVC Wisdom

Abstract: "Building a Twitter clone in 60 minutes, featuring what's new in ASP.NET MVC 2 preview 1 and focusing on some of the core ASP.NET MVC features like security and routing."