<?xml version="1.0" encoding="UTF-8"?> <rss
version="2.0"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:wfw="http://wellformedweb.org/CommentAPI/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
><channel><title>Arrange Act Assert &#187; MEF</title> <atom:link href="http://www.arrangeactassert.com/category/mef/feed/" rel="self" type="application/rss+xml" /><link>http://www.arrangeactassert.com</link> <description>Jag Reehal on Agile Development, ASP.NET MVC and all manner of good stuff</description> <lastBuildDate>Thu, 24 Nov 2011 00:01:20 +0000</lastBuildDate> <language>en</language> <sy:updatePeriod>hourly</sy:updatePeriod> <sy:updateFrequency>1</sy:updateFrequency> <generator>http://wordpress.org/?v=3.3.1</generator> <xhtml:meta xmlns:xhtml="http://www.w3.org/1999/xhtml" name="robots" content="noindex" /> <item><title>Applying the Open Closed Principle in Silverlight and WPF using MEF</title><link>http://www.arrangeactassert.com/applying-the-open-closed-principle-in-silverlight-and-wpf-using-mef/</link> <comments>http://www.arrangeactassert.com/applying-the-open-closed-principle-in-silverlight-and-wpf-using-mef/#comments</comments> <pubDate>Mon, 28 Jun 2010 23:27:39 +0000</pubDate> <dc:creator>Jag Reehal</dc:creator> <category><![CDATA[MEF]]></category> <category><![CDATA[Silverlight]]></category> <category><![CDATA[WPF]]></category><guid
isPermaLink="false">http://www.arrangeactassert.com/?p=900</guid> <description><![CDATA[In this post I want to show how MEF can be used to apply the Open Closed Principle where a class is open for extension but closed for modification. In the Calculator application we have been building as part of the Silverlight refactoring series we could have used the code below to validate a users [...]]]></description> <content:encoded><![CDATA[<p>In this post I want to show how <a
href="http://mef.codeplex.com/">MEF</a> can be used to apply the <a
href="http://en.wikipedia.org/wiki/Open/closed_principle">Open Closed Principle</a> where a class is open for extension but closed for modification.</p><p>In the Calculator application we have been building as part of the <a
href="http://www.arrangeactassert.com/how-to-refactor-and-build-better-microsoft-silverlight-applications/">Silverlight refactoring series</a> we could have used the code below to validate a users input.</p><p>By the way we are throwing exceptions because the application is using ValidatesOnExceptions.</p><pre class="brush: csharp; gutter: false; title: ; toolbar: true; notranslate">
public class CalculatorValidator
{
    public void ValidateNumber(string value)
    {
        if (String.IsNullOrEmpty(value))
        {
            throw new Exception(&quot;Please enter a number&quot;);
        }

        int number;
        if (!int.TryParse(value, out number))
        {
            throw new Exception(&quot;That's not a number&quot;);
        }
    }
}
</pre><p>If we wanted to add more validation rules to check the value cannot be negative or greater than a hundred we have to modify the CalculatorValidator class with two additional if statements.</p><pre class="brush: csharp; gutter: false; title: ; toolbar: true; notranslate">
public class CalculatorValidator
{
    public void ValidateNumber(string value)
    {
        if (String.IsNullOrEmpty(value))
        {
            throw new Exception(&quot;Please enter a number&quot;);
        }

        int number;
        if (!int.TryParse(value, out number))
        {
            throw new Exception(&quot;That's not a number&quot;);
        }

        if (number &lt; 0)
        {
            throw new Exception(&quot;Number cannot be negative&quot;);
        }

        if (number &gt; 100)
        {
            throw new Exception(&quot;That number is too big!&quot;);
        }
    }
}
</pre><p>and this pattern would continue every time you added a new rule, leaving the code as maintainable and stable as a wobbly tower!</p><h3 class="subheading">Implementing the Open Closed Principle</h3><p>Lets start by creating an interface for a validation rule</p><pre class="brush: csharp; gutter: false; title: ; toolbar: true; notranslate">
public interface ICalculatorValidationRule
{
    bool IsValid(string number);
    string ErrorMessage { get; }
}
</pre><p>Next we create a class for each validation rule by implementing the ICalculatorValidationRule interface</p><pre class="brush: csharp; gutter: false; title: ; toolbar: true; notranslate">
[Export(typeof(ICalculatorValidationRule))]
public class ValidateValueIsNotNullOrEmpty : ICalculatorValidationRule
{
    public bool IsValid(string value)
    {
        return !String.IsNullOrEmpty(value);
    }

    public string ErrorMessage
    {
        get
        {
            return &quot;Please enter a number&quot;;
        }
    }
}

[Export(typeof(ICalculatorValidationRule))]
public class ValidateValueIsANumber : ICalculatorValidationRule
{
    public bool IsValid(string value)
    {
        if (!String.IsNullOrEmpty(value))
        {
            int number;
            return int.TryParse(value, out number);
        }
        return true;
    }

    public string ErrorMessage
    {
        get { return &quot;That's not a number&quot;; }
    }
}

[Export(typeof(ICalculatorValidationRule))]
public class ValidateValueIsNotNegative : ICalculatorValidationRule
{
    public bool IsValid(string value)
    {
        int number;
        if (int.TryParse(value, out number) &amp;&amp; number  &lt; 0)
        {
            return false;
        }
        return true;
    }

    public string ErrorMessage
    {
        get { return &quot;Number cannot be negative&quot;; }
    }
}

[Export(typeof(ICalculatorValidationRule))]
public class ValidateValueIsLessThanHundred : ICalculatorValidationRule
{
    public bool IsValid(string value)
    {
        int number;
        if (int.TryParse(value, out number) &amp;&amp; number &gt; 100)
        {
            return false;
        }
        return true;
    }

    public string ErrorMessage
    {
        get { return &quot;That number is too big!&quot;; }
    }
}
</pre><p>An alternative to parsing the value to an integer in the validation rules to check the range would be to order how MEF composes the validation rules and ensure rule to validate the value is an integer is done earlier.</p><p>More information about this can be found in answer to this question on Stack Overflow &#8211; <a
href="http://stackoverflow.com/questions/1770297/how-does-mef-determine-the-order-of-its-imports/1772554">How does MEF determine the order of its imports?</a></p><h3 class="subheading">ImportMany example in MEF</h3><p>By using the ImportMany attribute on a collection in MEF we can iterate over all of the parts which export the ICalculatorValidatorInterface and check the value passes the validation rule by calling the IsValid method.</p><p>If the value is not valid a exception is thrown with the relevant error message.</p><p>The code below shows how the CalculatorValidator class would look</p><pre class="brush: csharp; gutter: false; title: ; toolbar: true; notranslate">
public class CalculatorValidator
{
    [ImportMany]
    public IEnumerable&lt;ICalculatorValidationRule&gt; CalculatorValidationRules { get; set; }

    public void ValidateNumber(string value)
    {
        foreach (var calculatorValidationRule in CalculatorValidationRules)
        {
            if (!calculatorValidationRule.IsValid(value))
            {
                throw new Exception(calculatorValidationRule.ErrorMessage);

            }
        }
    }
}
</pre><h3 class="subheading">Couldn&#8217;t have done it without the extensibility of MEF</h3><p>If we wanted to add a new validation rule, all we have to do is create another class which implements the ICalculatorValidationRule interface, add an export attribute and MEF will do the rest.</p><blockquote><p>The CalculatorValidator class is now open to extension but closed for modification</p></blockquote> ]]></content:encoded> <wfw:commentRss>http://www.arrangeactassert.com/applying-the-open-closed-principle-in-silverlight-and-wpf-using-mef/feed/</wfw:commentRss> <slash:comments>4</slash:comments> </item> <item><title>SOLID design principles using MEF in Silverlight and WPF</title><link>http://www.arrangeactassert.com/solid-design-principles-using-mef-in-silverlight-and-wpf/</link> <comments>http://www.arrangeactassert.com/solid-design-principles-using-mef-in-silverlight-and-wpf/#comments</comments> <pubDate>Thu, 17 Jun 2010 21:14:01 +0000</pubDate> <dc:creator>Jag Reehal</dc:creator> <category><![CDATA[MEF]]></category> <category><![CDATA[Silverlight]]></category> <category><![CDATA[WPF]]></category><guid
isPermaLink="false">http://www.arrangeactassert.com/?p=851</guid> <description><![CDATA[In this part of the Silverlight refactoring series we will be looking at two ways the Managed Extensibility Framework (MEF) can help you refactor Silverlight or WPF applications to follow SOLID design principles. The code used in this post can be downloaded here. Apart from saying through discovery and composition MEF gives you the ability [...]]]></description> <content:encoded><![CDATA[<p>In this part of the <a
href="http://www.arrangeactassert.com/how-to-refactor-and-build-better-microsoft-silverlight-applications/">Silverlight refactoring series</a> we will be looking at two ways the <a
href="http://mef.codeplex.com/">Managed Extensibility Framework (MEF)</a> can help you refactor Silverlight or WPF applications to follow <a
href="http://en.wikipedia.org/wiki/Solid_(object-oriented_design)">SOLID design principles</a>.</p><p>The code used in this post can be downloaded <a
ref="nofollow" href="http://cid-8a29bf85dc9538dc.office.live.com/self.aspx/.Public/Silverlight%20Demos/SilverlightCalculator/SilverlightCalculatorMEF.zip">here</a>.</p><p>Apart from saying</p><blockquote><p>through discovery and composition MEF gives you the ability to build applications which will be flexible enough for your every need</p></blockquote><p>I won’t be covering what MEF is or how it works in depth in this post.  Instead I recommend checking out the following blogs as well as the <a
href="http://mef.codeplex.com/">MEF site on Codeplex</a> for some great tutorials.</p><ul><li><a
href="http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/default.aspx">Mike Taulty&#8217;s Blog</a></li><li><a
href="http://blogs.msdn.com/b/gblock/">Glenn Block&#8217;s Blog</a></li></ul><h3 class="subheading">What problem does MEF solve in this application?</h3><p>The code below shows the Calculate method in the ViewModel.</p><pre class="brush: csharp; gutter: false; title: ; toolbar: true; notranslate">
public void  Calculate()
{
    Calculator calculator = new Calculator();
    Result = calculator.Add(Convert.ToInt32(FirstValue), Convert.ToInt32(SecondValue)).ToString();
}
</pre><p>Notice how Calculator class is created and used within the method.  This means there&#8217;s no way of changing what class is used for calculations without modifying the code in the ViewModel.</p><p>In other words <strong>the calculator is tightly coupled to the ViewModel</strong>.</p><h3 class="subheading">Composing, Initializing, Setting up, Bootstrapping, Configuring or whatever you want to call it in MEF</h3><p>MEF works by using a catalog to discover extensions within assemblies.  As the assemblies used in this application are in same XAP we can call the CompositionInitializer SatisfyImports method to automatically configure a container and compose the parts within it.</p><p>Looking at the class diagram for the application</p><p><img
src="http://www.arrangeactassert.com/wp-content/themes/resources/images/SilverlightMVVMViewModelSRP.png" alt="Silverlight Class Diagram" /></p><p>we could decide</p><ul><li>only the Calculator class will be an composable part</li><li>the ViewModel and the Calculator will be composable parts</li><li>the CalculatorPage, ViewModel and the class should all be composable parts</li></ul><p>As this application only contains a single page we will go with the second option.  This means we will be calling the CompositionInitializer SatisfyImport method in the CalculatorPage constructor as shown below</p><pre class="brush: csharp; gutter: false; title: ; toolbar: true; notranslate">
public CalculatorPage()
{
    InitializeComponent();
    CompositionInitializer.SatisfyImports(this);
}
</pre><h3 class="subheading">Adding MEF Export Attributes</h3><p>An export attribute is used to make classes and properties discoverable to the catalog and composable by the container.</p><p>As the Calculator class is used by the ViewModel we need to add an Export attribute to it. Because the Calculator implements the ICalculator interface we can use this as the <a
href="http://mef.codeplex.com/wikipage?title=Parts&#038;ANCHOR">contract type</a>.</p><pre class="brush: csharp; gutter: false; title: ; toolbar: true; notranslate">
[Export(typeof(ICalculator))]
public class Calculator : ICalculator
{
public int Add(int firstValue, int secondValue)
{
    return firstValue + secondValue;
}
}
</pre><p>Similarly as the ViewModel is used by the CalculatorPage it also needs to be decorated with an Export attribute.  As no contract is specified, MEF will use the fully qualified name of the type as the contract.</p><pre class="brush: csharp; gutter: false; title: ; toolbar: true; notranslate">
[Export]
public class CalculatorViewModel : INotifyPropertyChanged
{
    .....
}
</pre><p>An important thing to remember is that the export attribute is not allowed on the instance passed to SatisfyImports otherwise you will see the error below</p><p><img
src="http://www.arrangeactassert.com/wp-content/themes/resources/images/MEFExportError.png" alt="MEF Export Error" /></p><h3 class="subheading">Using MEF Property Imports</h3><p>To use property imports in MEF we need to add a Calculator property to the ViewModel add decorate it with an Import attribute.  In Silverlight MEF requires the property to be public.</p><pre class="brush: csharp; gutter: false; title: ; toolbar: true; notranslate">
[Import]
public ICalculator Calculator { get; set; }
</pre><p>The Calculate method in the ViewModel uses the property like this</p><pre class="brush: csharp; gutter: false; title: ; toolbar: true; notranslate">
public void Calculate()
{
    Result = Calculator.Add(Convert.ToInt32(FirstValue), Convert.ToInt32(SecondValue)).ToString();
}
</pre><p>In the code behind of the CalculatorPage we need to add a CalculatorViewModel property, decorate it with an Import attribute and set it as the data context.</p><pre class="brush: csharp; gutter: false; title: ; toolbar: true; notranslate">
public partial class CalculatorPage : UserControl
{
    [Import]
    public CalculatorViewModel CalculatorViewModel { get; set; }

    public CalculatorPage()
    {
        InitializeComponent();
        CompositionInitializer.SatisfyImports(this);
        DataContext = CalculatorViewModel;
    }
}
</pre><p>If we run the application as it is MEF composes all the parts of the application and we are able to add numbers together&#8230; which is good but not great because I don’t recommend you should build applications only using property imports.</p><h3 class="subheading">Using MEF Constructor Imports</h3><p>I always try to follow the SOLID design principles whenever I’m developing applications.</p><p>The D in SOLID design principles stands for <a
href="http://en.wikipedia.org/wiki/Dependency_inversion_principle">Dependency Inversion Principle</a>.</p><p>One of the first things you should be taught when learning test driven development or even good coding practices is how SOLID design principles will help you create applications that are easier to develop, configure, maintain and unit test.</p><p>See my blog post &#8216;<a
href="http://www.arrangeactassert.com/how-to-write-better-unit-tests-using-rhinomocks-and-stubs/">How to write better unit tests using RhinoMocks and stubs</a>&#8216; for an example.</p><p>The good news is MEF supports constructor imports.</p><p>Using the ImportingConstructor attribute the CalculatorViewModel now takes in a Calculator in its constructor as shown below</p><pre class="brush: csharp; gutter: false; title: ; toolbar: true; notranslate">
[ImportingConstructor]
public CalculatorViewModel(ICalculator calculator)
{
    _calculator = calculator;
    ...
}
</pre><p>and the calculate method uses the calculator like this</p><pre class="brush: csharp; gutter: false; title: ; toolbar: true; notranslate">
public void Calculate()
{
    Result = _calculator.Add(Convert.ToInt32(FirstValue), Convert.ToInt32(SecondValue)).ToString();
}
</pre><h3 class="subheading">Take care not to over engineer</h3><p>So what about the importing the ViewModel in the CalculatorPage?  We could stick to using a property for the ViewModel or pass it in the ViewModel constructor (in which case the call to CompositionInitializer SatisfyImports method will have to done in the App.xaml code behind).</p><p>I would be inclined to leave it as it is.  Because we want to be able to unit test the ViewModel it makes sense to use importing constructors so we stub out the calculator.</p><p>Are we ever going to unit test the CalculatorPage?  Probably not, and if we do need to, it’s not a major refactoring task.</p><p>In any case thanks to MEF the ViewModel can be changed without modifying the code behind for the CalculatorPage.</p><h3 class="subheading">So what have we achieved?</h3><p>By using SOLID design principles and MEF we have managed to remove the tight coupling between the ViewModel and the Calculator.</p><p>There is a lot of discussion about what MEF is in the development community.  Despite numerous claims and comments that it&#8217;s not a dependency injection framework, I can&#8217;t help thinking it takes a step closer to being one with each release.</p><p>The last thing I&#8217;ll say about MEF is that</p><blockquote><p>the number of options you have of using MEF is either impressive or confusing depending on what side of the fence you sit on</p></blockquote><p>If you have arrived here from a search engine, this post is part of series about <a
href="http://www.arrangeactassert.com/how-to-refactor-and-build-better-microsoft-silverlight-applications/">refactoring Silverlight applications</a>.</p><p>So if you’re thinking, what if there&#8217;s an exception converting a string into an integer, check out the post &#8216;<a
href="http://www.arrangeactassert.com/validation-in-silverlight-and-wpf-using-validatesonexceptions/">Validation in Silverlight and WPF using ValidatesOnExceptions</a>&#8216; which shows one approach in solving this problem using exceptions.</p> ]]></content:encoded> <wfw:commentRss>http://www.arrangeactassert.com/solid-design-principles-using-mef-in-silverlight-and-wpf/feed/</wfw:commentRss> <slash:comments>1</slash:comments> </item> </channel> </rss>
<!-- Served from: www.arrangeactassert.com @ 2012-02-06 00:12:00 by W3 Total Cache -->
