Logo

Maarten Balliauw {blog}

ASP.NET, ASP.NET MVC, Azure, PHP, OpenXML, VSTS, ...

About the author

Maarten Balliauw is currently employed as .NET Technical Consultant at RealDolmen. His interests are mainly web applications developed in ASP.NET (C#) or PHP and the Windows Azure cloud platform.
More about me More about me
Send mail E-mail me


ASP.NET MVC Quickly Subscribe to my RSS feed Follow me on Twitter! View Maarten Balliauw's profile on LinkedIn
View Maarten Balliauw's MVP profile

Search

Latest Twitter

    Follow me on Twitter...

    My projects

    Disclaimer

    The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

    © Copyright Maarten Balliauw 2010

    ASP.NET MVC - MvcSiteMapProvider 2.0 is out!

    I’m very proud to announce the release of the ASP.NET MVC MvcSiteMapProvider 2.0! I’m also proud that the name of this product now exceeds the average length of Microsoft product names. In this blog post, I will give you a feel of what you can (and can not) do with this ASP.NET-specific SiteMapProvider.

    As a warning: if you’ve used version 1 of this library, you will notice that I have not thought of backwards compatibility. A lot of principles have also changed. For good reasons though: this release is a rewrite of the original version with improved features, extensibility and stability.

    The example code is all based on the excellent ASP.NET MVC Music Store sample application by Jon Galloway.

    Getting the bits

    As always, the bits are available on CodePlex: MvcSiteMapProvider 2.0.0
    If you prefer to have the full source code, download the example application or check the source code tab on CodePlex.

    Introduction

    MvcSiteMapProvider is, as the name implies, an ASP.NET MVC SiteMapProvider implementation for the ASP.NET MVC framework. Targeted at ASP.NET MVC 2, it provides sitemap XML functionality and interoperability with the classic ASP.NET sitemap controls, like the SiteMapPath control for rendering breadcrumbs and the Menu control.

    Based on areas, controller and action method names rather than hardcoded URL references, sitemap nodes are completely dynamic based on the routing engine used in an application. The dynamic character of ASP.NET MVC is followed in the MvcSiteMapProvider: there are numerous extensibility points that allow you to extend the basic functionality offered.

    Registering the provider

    After downloading the MvcSiteMapProvider, you will have to add a reference to the assembly in your project. Also, you will have to register the provider in your Web.config file. Add the following code somewhere in the <system.web> section:

    <siteMap defaultProvider="MvcSiteMapProvider" enabled="true">
      <providers>
        <clear />
        <add name="MvcSiteMapProvider"
             type="MvcSiteMapProvider.DefaultSiteMapProvider, MvcSiteMapProvider"
             siteMapFile="~/Mvc.Sitemap"
             securityTrimmingEnabled="true"
             enableLocalization="true"
             scanAssembliesForSiteMapNodes="true"
             skipAssemblyScanOn=""
             attributesToIgnore="bling"
             nodeKeyGenerator="MvcSiteMapProvider.DefaultNodeKeyGenerator, MvcSiteMapProvider"
             controllerTypeResolver="MvcSiteMapProvider.DefaultControllerTypeResolver, MvcSiteMapProvider"
             actionMethodParameterResolver="MvcSiteMapProvider.DefaultActionMethodParameterResolver, MvcSiteMapProvider"
             aclModule="MvcSiteMapProvider.DefaultAclModule, MvcSiteMapProvider"
             />
      </providers>
    </siteMap>

    The following configuration directives can be specified:

    Directive Required? Default Description
    siteMapFile No ~/Web.sitemap The sitemap XML file to use.
    securityTrimmingEnabled No false Use security trimming? When enabled, nodes that the user can not access will not be displayed in any sitemap control.
    enableLocalization No false Enables localization of sitemap nodes.
    scanAssembliesForSiteMapNodes No false Scan assemblies for sitemap nodes defined in code?
    skipAssemblyScanOn No (empty) Comma-separated list of assemblies that should be skipped when scanAssembliesForSiteMapNodes is enabled.
    attributesToIgnore No (empty) Comma-separated list of attributes defined on a sitemap node that should be ignored by the MvcSiteMapProvider.
    nodeKeyGenerator No MvcSiteMapProvider.DefaultNodeKeyGenerator, MvcSiteMapProvider Class that will be used to generate sitemap node keys.
    controllerTypeResolver No MvcSiteMapProvider.DefaultControllerTypeResolver, MvcSiteMapProvider Class that will be used to resolve the controller for a specific sitemap node.
    actionMethodParameterResolver No MvcSiteMapProvider.DefaultActionMethodParameterResolver, MvcSiteMapProvider Class that will be used to determine the list of parameters on a sitemap node.
    aclModule No MvcSiteMapProvider.DefaultAclModule, MvcSiteMapProvider Class that will be used to verify security and access rules for sitemap nodes.

     

    Creating a first sitemap

    The following is a simple sitemap XML file that can be used with the MvcSiteMapProvider:

    <?xml version="1.0" encoding="utf-8" ?>
    <mvcSiteMap xmlns="http://mvcsitemap.codeplex.com/schemas/MvcSiteMap-File-2.0" enableLocalization="true">
      <mvcSiteMapNode title="Home" controller="Home" action="Index" changeFrequency="Always" updatePriority="Normal">
        <mvcSiteMapNode title="Browse Store" controller="Store" action="Index" />
        <mvcSiteMapNode title="Checkout" controller="Checkout" />
      </mvcSiteMapNode>
    </mvcSiteMap>

    The following attributes can be given on an XML node element:

    Attribute Required? Default Description
    title Yes (empty) The title of the node.
    description No (empty) Description of the node.
    area No (empty) The MVC area for the sitemap node. If not specified, it will be inherited from a node higher in the hierarchy.
    controller Yes (empty) The MVC controller for the sitemap node. If not specified, it will be inherited from a node higher in the hierarchy.
    action Yes (empty) The MVC action method for the sitemap node. If not specified, it will be inherited from a node higher in the hierarchy.
    key No (autogenerated) The unique identifier for the node.
    url No (autogenerated based on routes) The URL represented by the node.
    roles No (empty) Comma-separated list of roles allowed to access the node and its child nodes.
    resourceKey No (empty) Optional resource key.
    clickable No True Is the node clickable or just a grouping node?
    targetFrame No (empty) Optional target frame for the node link.
    imageUrl No (empty) Optional image to be shown by supported HtmlHelpers.
    lastModifiedDate No (empty) Last modified date for the node.
    changeFrequency No Undefined Change frequency for the node.
    updatePriority No Undefined Update priority for the node.
    dynamicNodeProvider No (empty) A class name implementing MvcSiteMapProvider.Extensibility.IDynamicNodeProvider and providing dynamic nodes for the site map.

     

    Defining sitemap nodes in code

    In some cases, defining a sitemap node in code is more convenient than defining it in a sitemap xml file. To do this, decorate an action method with the MvcSiteMapNodeAttribute attribute. For example:

    // GET: /Checkout/Complete
    [MvcSiteMapNodeAttribute(Title = "Checkout complete", ParentKey = "Checkout")]
    public ActionResult Complete(int id)
    {
        // ...
    }

    Note that the ParentKey property should be specified to ensure the MvcSiteMapProvider  can determine the hierarchy for all nodes.

    Dynamic sitemaps

    In many web applications, sitemap nodes are directly related to content in a persistent store like a database.For example, in an e-commerce application, a list of product details pages in the sitemap maps directly to the list of products in the database. Using dynamic sitemaps, a small class can be provided to the MvcSiteMapProvider offering a list of dynamic nodes that should be incldued in the sitemap. This ensures the product pages do not have to be specified by hand in the sitemap XML.

    First of all, a sitemap node should be defined in XML. This node will serve as a template and tell the MvcSiteMapProvider infrastructure to use a custom dynamic node procider:

    <mvcSiteMapNode title="Details" action="Details" dynamicNodeProvider="MvcMusicStore.Code.StoreDetailsDynamicNodeProvider, MvcMusicStore" />

    Next, a class implementing MvcSiteMapProvider.Extensibility.IDynamicNodeProvider or extending MvcSiteMapProvider.Extensibility.DynamicNodeProviderBase should be created in your application code. Here’s an example:

    public class StoreDetailsDynamicNodeProvider
        : DynamicNodeProviderBase
    {
        MusicStoreEntities storeDB = new MusicStoreEntities();

        public override IEnumerable<DynamicNode> GetDynamicNodeCollection()
        {
            // Build value
            var returnValue = new List<DynamicNode>();

            // Create a node for each album
            foreach (var album in storeDB.Albums.Include("Genre"))
            {
                DynamicNode node = new DynamicNode();
                node.Title = album.Title;
                node.ParentKey = "Genre_" + album.Genre.Name;
                node.RouteValues.Add("id", album.AlbumId);

                returnValue.Add(node);
            }

            // Return
            return returnValue;
        }
    }

    Cache dependency

    When providing dynamic sitemap nodes to the MvcSiteMapProvider, chances are that the hierarchy of nodes will become stale, for example when adding products in an e-commerce website. This can be solved by specifying a CacheDescriptor on your MvcSiteMapProvider.Extensibility.IDynamicNodeProvider implementation:

    public class StoreDetailsDynamicNodeProvider
        : DynamicNodeProviderBase
    {
        MusicStoreEntities storeDB = new MusicStoreEntities();

        public override IEnumerable<DynamicNode> GetDynamicNodeCollection()
        {
            // ...
        }

        public override CacheDescription GetCacheDescription()
        {
            return new CacheDescription("StoreDetailsDynamicNodeProvider")
            {
                SlidingExpiration = TimeSpan.FromMinutes(1)
            };
        }
    }

    HtmlHelper functions

    The MvcSiteMapProvider provides different HtmlHelper extension methods which you can use to generate SiteMap-specific HTML code on your ASP.NET MVC views. Here's a list of available HtmlHelper extension methods.

    • Html.MvcSiteMap().Menu() - Can be used to generate a menu
    • Html.MvcSiteMap().SubMenu() - Can be used to generate a submenu
    • Html.MvcSiteMap().SiteMap() - Can be used to generate a list of all pages in your sitemap
    • Html.MvcSiteMap().SiteMapPath() - Can be used to generate a so-called "breadcrumb trail"
    • Html.MvcSiteMap().SiteMapTitle() - Can be used to render the current SiteMap node's title

    Note that these should be registered in Web.config, i.e. under <pages> add the following:

    <pages>
        <controls>
            <! -- ... -->
        </controls>
        <namespaces>
            <! -- ... -->
            <add namespace="MvcSiteMapProvider.Web.Html" />
        </namespaces>
    </pages>

    Action Filter Attributes

    SiteMapTitle

    In some situations, you may want to dynamically change the SiteMap.CurrentNode.Title in an action method. This can be done manually by setting SiteMap.CurrentNode.Title, or by adding the SiteMapTitle action filter attribute.

    Imagine you are building a blog and want to use the Blog's Headline property as the site map node title. You can use the following snippet:

    [SiteMapTitle("Headline")]
    public ViewResult Show(int blogId) {
       var blog = _repository.Find(blogIdId);
       return blog;
    }

    You can also use a non-strong typed ViewData value as the site map node title:

    [SiteMapTitle("SomeKey")]
    public ViewResult Show(int blogId) {
       ViewData["SomeKey"] = "This will be the title";

       var blog = _repository.Find(blogIdId);
       return blog;
    }

    Exporting the sitemap for search engine indexing

    When building a website, chances are that you want to provide an XML sitemap used for search engine indexing. The XmlSiteMapResult class creates an XML sitemap that can be submitted to Google, Yahoo and other search engines to help them crawl your website better. The usage is very straightforward:

    public class HomeController
    {
        public ActionResult SiteMapXml()
        {
            return new XmlSiteMapResult();
        }
    }

    Optionally, a starting node can also be specified in the constructor of theXmlSiteMapResult .

    Conclusion

    Get it while it’s hot! MvcSiteMapProvider 2.0.0 is available on CodePlex.

    kick it on DotNetKicks.com


    Categories: ASP.NET | C# | General | MVC | Projects | Software | XML

    Extension methods for PHP

    PHP Extension Methods The concept of “extension” methods will be nothing new to this blog’s .NET-related audience. For the PHP-related audience, this is probably something new. Let’s start with the official definition for extension methods: Extension methods enable you to "add" methods to existing types without creating a new derived type, recompiling, or otherwise modifying the original type. Extension methods are a special kind of static method, but they are called as if they were instance methods on the extended type.

    Let’s visualize this. Imagine having the following class:

    class HelloWorld
    {
        public function sayHello($to = 'World', $from = null)
        {
            $helloString = "Hello, " . $to . "!";
            if (!is_null($from)) {
                $helloString .= " From " . $from;
            }

            echo $helloString . "\r\n";
        }
    }

    Not too difficult. There’s a sayHello() method that allows you to optionally pass who should be greeted and who the greeting is from. Imagine you would like to have a sayHelloTo() method as well, a shortcut to sayHello($to). And some other helper methods that use sayHello() under the hood. Wouldn’t it be nice to have the HelloWorld class concentrating on the real logic and defining the helper/utility functions somewhere else? How about a class named HelloExtensions:

    class HelloWorldExtensions
    {
        public static function sayHelloTo(HelloWorld $subject, $name = '')
        {
            $subject->sayHello($name);
        }

        public static function sayHelloFrom(HelloWorld $subject, $name = '')
        {
            $subject->sayHello('World', $name);
        }
    }

    Ok, nice. But this means I should call HelloWorldExtensions::sayHelloTo(‘Maarten’); to use the utility functions, right? Well: no! Not if we implement the concept of extension methods. Let’s see what we can do to HelloWorld in order to make our life easier.

    class HelloWorld
    {
        public function sayHello($to = 'World', $from = null)
        {
            $helloString = "Hello, " . $to . "!";
            if (!is_null($from)) {
                $helloString .= " From " . $from;
            }

            echo $helloString . "\r\n";
        }

        public function __call($functionName, $arguments = array())
        {
            // Add an extra parameter
            array_unshift($arguments, $this);

            // Current reflected class
            $reflectedClass = new reflectionObject($this);

            // Find suitable class and function
            $availableClasses = get_declared_classes();
            foreach ($availableClasses as $class) {
                $classDefinition = new ReflectionClass($class);
                $availableMethods = $classDefinition->getMethods();
                foreach ($availableMethods as $method) {
                    if ($method->isStatic() && $method->getName() == $functionName) {
                        $availableParameters = $method->getParameters();
                        if ($availableParameters[0]->getClass()->getName() == $reflectedClass->getName()) {
                            $method->invokeArgs(null, $arguments);
                        }
                    }
                }
            }
        }
    }

    The magic method __call() is used to look for a class that defines a static method with the first parameter of our type, HelloWorld. This now allows us to write very clean calls to code, as well as simplify our HelloWorld class:

    $helloWorld = new HelloWorld();
    $helloWorld->sayHello();
    $helloWorld->sayHelloTo('Maarten');
    $helloWorld->sayHelloFrom('Maarten');

    Sweet, no? Can someone get this into the PHP core? I would greatly appreciate it: my classes can focus on functionality and all utility functions that just pass around variables can be defined in a separate class.


    MEF will not get easier, it’s cool as ICE

    Over the past few weeks, several people asked me to show them how to use MEF (Managed Extensibility Framework), some of them seemed to have some difficulties with the concept of MEF. I tried explaining that it will not get easier than it is currently, hence the title of this blog post. MEF is based on 3 keywords: export, import, compose. Since these 3 words all start with a letter that can be combined to a word, and MEF is cool, here’s a hint on how to remember it: MEF is cool as ICE!

    kick it on DotNetKicks.com

    Imagine the following:

    You want to construct a shed somewhere in your back yard. There’s tools to accomplish that, such as a hammer and a saw. There’s also material, such as nails and wooden boards.

    Let’s go for this! Here’s a piece of code to build the shed:

    public class Maarten
    {
        public void Execute(string command)
        {
            if (command == “build-a-shed”)
            {
              List<ITool> tools = new List<ITool>
              {
                new Hammer(),
                new Saw()
              };

              List<IMaterial> material = new List<IMaterial>
              {
                new BoxOfNails(),
                new WoodenBoards()
              };

              BuildAShedCommand task = new BuildAShedCommand(tools, material);
              task.Execute();
            }
        }
    }

    That’s a lot of work, building a shed! Imagine you had someone to do the above for you, someone who gathers your tools spread around somewhere in the house, goes to the DIY-store and gets a box of nails, … This is where MEF comes in to place.

    Compose

    Let’s start with the last component of the MEF paradigm: composition. Let’s not look for tools in the garage (and the attic), let’s not go to the DIY store, let’s “outsource” this task to someone cheap: MEF. Cheap because it will be in .NET 4.0, not because it’s, well, “cheap”. Here’s how the outsourcing would be done:

    public class Maarten
    {
        public void Execute(string command)
        {
            if (command == “build-a-shed”)
            {
              // Tell MEF to look for stuff in my house, maybe I still have nails and wooden boards as well
              AssemblyCatalog catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
              CompositionContainer container = new CompositionContainer(catalog);

              // Start the job, and ask MEF to find my tools and material
              BuildAShedCommand task = new BuildAShedCommand();
              container.ComposeParts(task);
              task.Execute();
            }
        }
    }

    Cleaner, no? The only thing I have to do is start the job, which is more fun when my tools and material are in reach. The ComposeParts() call figures out where my tools and material are. However, MEF's stable composition promise will only do that if it can find ("satisfy") all required imports. And MEF will not know all of this automatically. Tools and material should be labeled. And that’s where the next word comes in play: export.

    Export

    Export, or the ExportAttribute to be precise, is a marker for MEF to tell that you want to export the type or property on which the attribute is placed. Really think of it like a label. Let’s label our hammer:

    [Export(typeof(ITool))]
    public class Hammer : ITool
    {
      // ...
    }

    The same should be done for the saw, the box of nails and the wooden boards. Remember to put a different label color on the tools and the material, otherwise MEF will think that sawing should be done with a box of nails.

    Import

    Of course, MEF can go ahead and gather tools and material, but it will not know what to do with it unless you give it a hint. And that’s where the ImportAttribute (and the ImportManyAttribute) come in handy. I will have to tell MEF that the tools go on one stack, the material goes on another one. Here’s how:

    public class BuildAShedCommand : ICommand
    {
      [ImportMany(typeof(ITool))]
      public IEnumerable<ITool> Tools { get; set; }

      [ImportMany(typeof(IMaterial))]
      public IEnumerable<IMaterial> Materials { get; set; }

      // ...
    }

    Conclusion

    Easy, no? Of course, MEF can do a lot more than this. For instance, you can specify that a certain import is only valid for exports of a specific type and specific metadata: I can have a small and a large hammer, both ITool. For building a shed, I will require the large hammer though.

    Another cool feature is creating your own export provider (example at TheCodeJunkie.com). And if ICE does not make sense, try the Zoo example.

    kick it on DotNetKicks.com


    Microsoft Web Development Summit 2009

    PHP at Microsoft Being in the US for 2 times in a month (PDC09 and Web Development Summit) is fun, tiring and rewarding. The WDS09 was an invite-only event organized by Microsoft, focusing on interaction between Microsoft and the PHP community. I must say: the event has been helpful and interesting for both parties!

    • The Heathman Hotel in Kirkland is a nice hotel!
    • Traveling towards the US is far more productive than flying back: I did PHPMEF traveling westbound, I crashed (half sleep/half awake) on the eastbound flight…
    • If you just traveled over 26 hours: do NOT go shopping immediately when you arrive home! It’s really frustrating and tiring.
    • Did a session on Windows Azure SDK for PHP, PHPExcel and PHPLinq.
    • Did an interview for the Connected Show
    • Met a lot of people I knew from Twitter and e-mail, and met a lot of new people, both Microsoft and PHP community. Nice to meet you all!
    • Event focus was on feedback between Microsoft and PHP community, overall I think the dialogue was respectful and open and helpful to both parties.

    Standing at the Microsoft logo

    This was actually my first time at the WDS which has been around for 5 years already. The Interop team invited me there, and I want to thank them for doing that: it was a great trip, a great event and I got the chance to meet lots of new people.

    Attendees were mostly people from the PHP community, like Cal Evans, Rafael Doms, Chris Cornutt, Romain Bourdon (WAMP server anyone?), Alison “snipe” Gianotto, … Next to that, lots of Microsoft people came by during various sessions. Some of them even reserved the whole week and were attending all sessions to make sure they were in the feedback loop all the time.

    We’ve seen Microsoft sessions on IIS, Web Platform Installer, Silverlight, SQL Server, Bing, Powershell (sorry, Scott Hanselman, for disturbing your presentation with a tweet :-)). Interesting sessions with some info I did not know. PHP community sessions were also available: Wordpress, Joomla, Drupal, the PHP community perspective, feedback sessions, PHPLinq, PHPExcel, interoperability bridges, … A good mix of content with knowledgeable speakers and good communication between speakers, product groups and audience. Well done!


    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:

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

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

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

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

    class Calculator
    {
        public $CalculationFunctions;
    }

    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:

    /**
      * @export ICalculationFunction
      */

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

    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:

    class Calculator
    {
        /**
          * @import ICalculationFunction
          */

        public $SomeFunction;
    }

    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:

    class Calculator
    {
        /**
          *  @import-many ICalculationFunction
          */

        public $CalculationFunctions;
    }

    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!

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

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

    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:

    /**
      * @export ICalculationFunction
      * @export-metadata singleinstance
      */

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

    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:

    class Calculator
    {
        /**
          *  @import-many ICalculationFunction
          */

        public $CalculationFunctions;

        /**
          *  @import ICalculationFunction
          *  @import-metadata CanDoSums
          */

        public $SomethingThatCanDoSums;
    }

    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:

    /**
      * @export ICalculationFunction
      * @export-metadata CanDoSums
      */

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

    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.

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

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

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

    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 :-)


    Categories: General | MEF | PHP | Projects | Software

    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/


    Categories: Azure | C# | General | PHP | Software

    Simple API for Cloud Application Services

    Zend, in co-operation with IBM, Microsoft, Rackspace, GoGrid and other cloud leaders, today have released their Simple API for Cloud Application Services project. The Simple Cloud API project empowers developers to use one interface to interact with the cloud services offered by different vendors. These vendors are all contributing to this open source project, making sure the Simple Cloud API “fits like a glove” on top of their service.

    Zend Cloud adapters will be available for services such as:

    • File storage services, including Windows Azure blobs, Rackspace Cloud Files, Nirvanix Storage Delivery Network and Amazon S3
    • Document Storage services, including Windows Azure tables and Amazon SimpleDB
    • Simple queue services, including Amazon SQS and Windows Azure queues

    Note that the Simple Cloud API is focused on providing a simple and re-usable interface across different cloud services. This implicates that specific features a service offers will not be available using the Simple Cloud API.

    Here’s a quick code sample for the Simple Cloud API. Let’s upload some data and list the items in a Windows Azure Blob Storage container using the Simple Cloud API:

    require_once('Zend/Cloud/Storage/WindowsAzure.php');

    // Create an instance
    $storage = new Zend_Cloud_Storage_WindowsAzure(
    'zendtest',
    array(
      'host' => 'blob.core.windows.net',
      'accountname' => 'xxxxxx',
      'accountkey' => 'yyyyyy'
    ));

    // Create some data and upload it
    $item1 = new Zend_Cloud_Storage_Item('Hello World!', array('creator' => 'Maarten'));
    $storage->storeItem($item1, 'data/item.txt');

    // Now download it!
    $item2 = $storage->fetchItem('data/item.txt', array('returntype' => 2));
    var_dump($item2);

    // List items
    var_dump(
    $storage->listItems()
    );

    It’s quite fun to be a part of this kind of things: I started working for Microsoft on the Windows Azure SDK for PHP, we contributed the same codebase to Zend Framework, and now I’m building the Windows Azure implementations for the Simple Cloud API.

    The full press release can be found at the Simple Cloud API website.


    SQL Azure Manager

    image

    A few days ago, the SQL Server Team announced the availability of three major CTP’s and several new upcoming projects in the SQL related family tree: SQL Server 2008 R2, SQL Server StreamInsight and SQL Azure. Now that last one is interesting: Microsoft will offer a 1GB or 10GB database server “in the cloud” for a good price.

    Currently, SQL Azure is in CTP and will undergo some more development. Of course, I wanted to play with this, but… connecting to the thing using SQL Server management Studio is not the most intuitive and straightforward task. It’s more of a workaround. Juliën Hanssens, a colleague of mine, was going crazy for this. Being a good colleague, I poored some coffee tea in the guy and he came up with the SQL Azure manager: a community effort to quickly enable connecting to your SQL Azure database(s) and perform basic tasks.

    SQL Azure Manager

    And it does just that. Note that it is a first conceptual release. And that it is still a bit unstable. But it does the trick. At least at a bare minimum. And for the time being that is enough. Want to play with it? Check Juliën’s ClickOnce page!

    Note that this thing will become open-soucre in the future, after he finds a good WF designer to do the main UI. Want to help him? Use the submit button!

    kick it on DotNetKicks.com


    Categories: Azure | C# | General | Projects | Software | SQL Azure

    Application-wide action filters in ASP.NET MVC

    Ever had a team of developers using your ASP.NET MVC framework? Chances are you have implemented some action filters (i.e. for logging) which should be applied on all controllers in the application. Two ways to do this: kindly ask your developers to add a [Logging] attribute to the controllers they write, or kindly ask to inherit from SomeCustomControllerWithActionsInPlace.

    If you have been in this situation, monday mornings, afternoons, tuesdays and other weekdays are in fact days where some developers will forget to do one of the above. This means no logging! Or any other action filters that are executed due to a developer that has not been fed with enough coffee… Wouldn’t it be nice to have a central repository where you can register application-wide action filters? That’s exactly what we are going to do in this blog post.

    Note: you can in fact use a dependency injection strategy for this as well, see Jeremy Skinner’s blog.

    Download the example code: MvcGlobalActionFilter.zip (24.38 kb)

    kick it on DotNetKicks.com

    The idea

    Well, all things have to start with an idea, otherwise there’s nothing much left to do. What we’ll be doing in our solution to global action filters is the following:

    1. Create a IGlobalFilter interface which global action filters have to implement. You can discuss about this, but I think it’s darn handy to add some convenience methods like ShouldBeInvoked() where you can abstract away some checks before the filter is actually invoked.
    2. Create some IGlobalActionFilter, IGlobalResultFilter, IGlobalAuthorizationFilter, IGlobalExceptionFilter interfaces, just for convenience to the developer that is creating the global filters. You’ll see the use of this later on.
    3. Create a GlobalFilterActionInvoker, a piece of logic that is set on each controller so the controller knows how to call its own action methods. We’ll use this one to inject our lists of global filters.
    4. Create a GlobalFilterControllerFactory. I’m not happy with this, but we need it to set the GlobalFilterActionInvoker instance on each controller when it is created.

    IGlobalFilter, IGlobalActionFilter, …

    Not going to spend too much time on these. Actually, these interfaces are just descriptors for our implementation so it knows what type of filter is specified and if it should be invoked. Here’s a bunch of code. No comments.

    public interface IGlobalFilter
    {
        bool ShouldBeInvoked(ControllerContext controllerContext);
    }

    public interface IGlobalAuthorizationFilter : IGlobalFilter, IAuthorizationFilter

    public interface IGlobalActionFilter : IGlobalFilter, IActionFilter { }

    public interface IGlobalResultFilter : IGlobalFilter, IResultFilter { }

    public interface IGlobalExceptionFilter : IGlobalFilter, IExceptionFilter { }

    And yes, I did suppress some Static Code Analysis rules for this :-)

    GlobalFilterActionInvoker

    The GlobalFilterActionInvoker will take care of registering the global filters and making sure each filter is actually invoked on every controller and action method in our ASP.NET MVC application. Here’s a start for our class:

    public class GlobalFilterActionInvoker : ControllerActionInvoker
    {
        protected FilterInfo globalFilters;

        public GlobalFilterActionInvoker()
        {
            globalFilters = new FilterInfo();
        }

        public GlobalFilterActionInvoker(FilterInfo filters)
        {
            globalFilters = filters;
        }

        public GlobalFilterActionInvoker(List<IGlobalFilter> filters)
            : this(new FilterInfo())
        {
            foreach (var filter in filters)
                RegisterGlobalFilter(filter);
        }

        public FilterInfo Filters
        {
            get { return globalFilters; }
        }

        // - more code -

    }

    We’re providing some utility constructors that take a list of global filters and add it to the internal FilterInfo instance (which is an ASP.NET MVC class we can leverage in here). RegisterGlobalFilter() will do the magic of adding filters to the right collection in the FilterInfo instance.

    public void RegisterGlobalFilter(IGlobalFilter filter)
    {
        if (filter is IGlobalAuthorizationFilter)
            globalFilters.AuthorizationFilters.Add((IGlobalAuthorizationFilter)filter);

        if (filter is IGlobalActionFilter)
            globalFilters.ActionFilters.Add((IGlobalActionFilter)filter);

        if (filter is IGlobalResultFilter)
            globalFilters.ResultFilters.Add((IGlobalResultFilter)filter);

        if (filter is IGlobalExceptionFilter)
            globalFilters.ExceptionFilters.Add((IGlobalExceptionFilter)filter);
    }

    One override left in our implementation: ControllerActionInvoker, the class we are inheriting from, provides a method named GetFilters(), which is used to get the filters for a specific controller context. Ideal one to override:

    protected override FilterInfo GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor)
    {
        FilterInfo definedFilters = base.GetFilters(controllerContext, actionDescriptor);

        foreach (var filter in Filters.AuthorizationFilters)
        {
            IGlobalFilter globalFilter = filter as IGlobalFilter;
            if (globalFilter == null ||
                (globalFilter != null && globalFilter.ShouldBeInvoked(controllerContext)))
            {
                definedFilters.AuthorizationFilters.Add(filter);
            }
        }

        // - same for action filters -

        // - same for result filters -

        // - same for exception filters -

        return definedFilters;
    }

    Basically, we are querying our IGlobalFilter if it should be invoked for the given controller context. If so, we add it to the FilterInfo object that is required by the ControllerActionInvoker base class. Piece of cake!

    GlobalFilterControllerFactory

    I’m not happy having to create this one, but we need it to set the GlobalFilterActionInvoker instance on each controller that is created. Otherwise, there is no way to specify our global filters on a controller or action method… Here’s the class:

    public class GlobalFilterControllerFactory : DefaultControllerFactory
    {
        protected GlobalFilterActionInvoker actionInvoker;

        public GlobalFilterControllerFactory(GlobalFilterActionInvoker invoker)
        {
            actionInvoker = invoker;
        }

        public override IController CreateController(System.Web.Routing.RequestContext requestContext, string controllerName)
        {
            IController controller = base.CreateController(requestContext, controllerName);
            Controller controllerInstance = controller as Controller;
            if (controllerInstance != null)
            {
                controllerInstance.ActionInvoker = actionInvoker;
            }
            return controller;
        }
    }

    What we do here is let the DefaultControllerFactory create a controller. Next, we simply set the controller’s ActionInvoker property to our GlobalFilterActionInvoker .

    Plumbing it all together!

    To plumb things together, add some code in your Global.asax.cs class, under Application_Start:

    protected void Application_Start()
    {
        RegisterRoutes(RouteTable.Routes);

        ControllerBuilder.Current.SetControllerFactory(
            new GlobalFilterControllerFactory(
                new GlobalFilterActionInvoker(
                    new List<IGlobalFilter>
                    {
                        new SampleGlobalTitleFilter()
                    }
                )
            )
        );
    }

    We are now setting the controller factory for our application to GlobalFilterControllerFactory, handing it a GlobalFilterActionInvoker which specifies one global action filter: SampleGlobalTitleFilter.

    Sidenote: SampleGlobalTitleFilter

    As a sidenote, I created a sample result filter named SampleGlobalTitleFilter, which is defined as a global filter that always appends a string (“ – Sample Application”) to the page title. Here’s the code for that one:

    public class SampleGlobalTitleFilter : IGlobalResultFilter
    {
        public bool ShouldBeInvoked(System.Web.Mvc.ControllerContext controllerContext)
        {
            return true;
        }

        public void OnResultExecuted(System.Web.Mvc.ResultExecutedContext filterContext)
        {
            return;
        }

        public void OnResultExecuting(System.Web.Mvc.ResultExecutingContext filterContext)
        {
            if (filterContext.Controller.ViewData["PageTitle"] == null)
                filterContext.Controller.ViewData["PageTitle"] = "";

            string pageTitle = filterContext.Controller.ViewData["PageTitle"].ToString();

            if (!string.IsNullOrEmpty(pageTitle))
                pageTitle += " - ";

            pageTitle += "Sample Application";

            filterContext.Controller.ViewData["PageTitle"] = pageTitle;
        }
    }

    Conclusion

    Download the sample code: MvcGlobalActionFilter.zip (24.38 kb)

    There is no need for my developers to specify SampleGlobalTitleFilter on each controller they write. There is no need for my developers to use the ControllerWithTitleFilter base class. People can come in and even develop software without drinking 2 liters of coffee! Really, development should not be hard for your developers. Make sure all application-wide infrastructure is there and our people are ready to go. And I’m really loving ASP.NET MVC’s extensibility on that part!

    kick it on DotNetKicks.com


    Categories: ASP.NET | C# | General | MVC | Software

    Mocking - VISUG session (screencast)

    A new screencast has just been uploaded to the MSDN Belgium Chopsticks page. Don't forget to rate the video!

    Mocking - VISUG session (screencast)

    Abstract: "This session provides an introduction to unit testing using mock objects. It builds a small application using TDD (test driven development). To enable easier unit testing, all dependencies are removed from code and introduced as mock objects. Afterwards, a mocking framework by the name of Moq (mock you) is used to shorten unit tests and create a maintainable set of unit tests for the example application. "

    Slides and example code can be found in my previous blog post on this session: Mocking - VISUG session

    kick it on DotNetKicks.com