Nov 082015
 

Since first using ASP.NET 5 and MVC 6 I’ve been fighting the EF-based Identity framework. I can’t do much about the rather obtuse API, but I can fix the constant moaning about migrations and terrible performance by replacing the EF data stores with something a little (OK a LOT) better. I’m a big fan of the new ‘micro’ ORMs out there like PetaPOCO, Dapper, Massive, etc. They’re extremely easy to use, and incredibly fast – almost as fast as manually typing out ADO.NET commands yourself but without the pain. At work I use NPOCO, which is an extended and in my opinion ‘better’ version of PetaPOCO.

While the API for ASP.NET Identity may be ‘odd’, Microsoft have made it quite easy to extend / change the framework. Removing the hard dependency on Entity Framework is a simple case of replacing the ‘UserStore’ and ‘RoleStore’ with your own implementations. Technically you only have to support the features you’re actually using. But it’s pretty easy to support everything but the ‘Queryable’ functionality, and you do this by implementation various interfaces such as:

  • IUserLoginStore<TUser>
  • IUserRoleStore<TUser>
  • IUserClaimStore<TUser>
  • IUserPasswordStore<TUser>
  • IUserSecurityStampStore<TUser>
  • IUserEmailStore<TUser>
  • IUserLockoutStore<TUser>
  • IUserPhoneNumberStore<TUser>
  • IUserTwoFactorStore<TUser>

Part of the reason the storage API is so over-engineered is so that the system can support both databases and remote services without impacting on performance too much. The disadvantage, ironically, is that performance is slightly lower if you’re using a traditional database as the data store. It also means when using Identity you have to explicitly ask for things, rather than being able to fetch a user and immediately see the available roles for example.

Microsoft have completely open-sourced Identity so you can see the default implementation over at GitHub here. I used this code as the basis for my own implementation. Of particular interest are the UserStore and RoleStore classes in the EntityFramework project.

I’ve open sourced my implementation and made it available on GitHub here. In short you lost almost no functionality, yet gain a staggering performance gain of up to 1,136%. You can easily transition from your current EF version to the new NPOCO version since the DB schema is identical (in fact I’ve just stolen MS’ schema for compatibility purposes). You can still use your own custom user and role classes as long as they inherit from IdentityUser and IdentityRole – just like with the MS EF version.

 Posted by at 18:05
Oct 142014
 

When you first start working with Inversion of Control (might have to write a blog post on that…) & unit testing you’ll probably go interface crazy! Interfaces are great, and they really make it easy to unit test and take full advantage of inversion of control. However, sometimes you don’t want to use one. Fortunately if you’re using design patterns properly, it’s easy to decide if you need to use an interface or not:

  • Is the class just data storage? If so, it should always just be a concrete type
  • Is the class a service that does something? If so it should always have an interface

The problem is when you’ve got a class that’s mostly data storage but also has some logic to it. In this case you’ve broken ‘Separation of Concerns’ and now have a problem! In this case you’ll want to expose an interface simply to make testing easier. However, ideally you want to refactor the logic out into one or more new classes.

Oct 142014
 

It’s been a while since I’ve written anything, mostly because almost any ‘how to’ has already been written. So let’s start looking into the more difficult realm of architecture of the application rather than how to do this or that.

Encapsulation is one of the basic tenants of Object Oriented programming, and is often over-looked. In short encapsulation means hiding the internal functionality away from the consumer of your class. But what does that actually mean?

It means you’ve got some difficult decisions to make with each class you build! To make my point I’m going to use a class that accesses a database. In this class we’re going to save people, think of it like a contacts list. This ‘PeopleList’ is going to save people, and then later fetch people from a database. A naive approach might have the following methods:

  • InsertPerson
  • UpdatePerson
  • DeletePerson
  • GetPerson
  • GetPeople

Where has the encapsulation been lost? It’s been lost with the Insert/Update methods, both of which are shouting that you’re using a SQL database and you’re exposing the underlying requirements of the DB to the user of your class. The users of your class doesn’t care about the database you use, just that they want to persist people and then fetch them. Differentiating between inserts and updates is not relevant to the users of the class, and just adds additional work for them.

This is one of the most important things you must do each time you design a class – consider what does the user of the class want to do? You then make that task as easy as possible. You only write the class once, but this class might be used many thousands of times over many years. A better approach would be to have the following methods instead:

  • SavePerson
  • DeletePerson
  • GetPerson
  • GetPeople

Now your class is much simpler to use. Does the user have to consider if they have already saved the person anymore? No, now all they need to do is throw a person at your class and you worry about the details. You’ve encapsulated the functionality so that the user doesn’t have to worry about logic you should be worrying about.

The great thing about doing this, is the underlying data store of this class can now be changed without any changes to the public interface of the class. We could use web service instead, and you’re still handling the logic yourself. If the web services are well designed you’ve effectively reduced the query count by one since the user of your class won’t have to check if the person exists already or not. Not only is it easier to use your new class, but it’s faster too!

Coming soon: Encapsulation Part 2!

Jan 222013
 

AutoResizeTextView Example

If you need your TextView to automatically shrink the text to fit (rather than truncating), Andreas Krings has a great solution. However, this solution is written in Java rather than C#. So here I present a version ported to Mono for Android using C#.

The implementation is pretty much identical, with a default minimum size of 10dp. The TextView will then attempt to find the largest size possible for the text that will fit the frame (the one limitation is that only the horizontal dimension is taken into account), with a maximum size of the initial size; and a minimum size of 10dp (unless overridden).  Usage is the same as well:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res/com.danclarke.AutoResizeTextView"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <TextView
        android:text="Normal TextView"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:id="@+id/textView1" />
    <TextView
        android:text="@string/longString"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:textSize="25dp"
        android:height="50dp" />

    <TextView
        android:text="AutoResizeTextView"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:id="@+id/textView2"
        android:layout_marginTop="20dp" />
    <AutoResizeTextView.Controls.AutoResizeTextView
        android:text="@string/longString"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:textSize="25dp"
        android:height="50dp" />

    <TextView
        android:text="AutoResizeTextView with minTextSize"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:id="@+id/textView3"
        android:layout_marginTop="20dp" />
    <AutoResizeTextView.Controls.AutoResizeTextView
        android:text="@string/longString"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:textSize="25dp"
        android:height="50dp"
        app:minTextSize="20dp" />
</LinearLayout>

Don’t forget to view the full project at GitHub!

Code Listing

For the impatient, here’s the full control’s code listing:

using System;

using Android.Content;
using Android.Runtime;
using Android.Widget;
using Android.Util;
using Android.Graphics;

namespace AutoResizeTextView.Controls
{
    /// <summary>
    /// TextView that automatically resizes it's content to fit the layout dimensions
    /// </summary>
    /// <remarks>Port of: http://ankri.de/autoscale-textview/</remarks>
    public class AutoResizeTextView : TextView
    {
        /// <summary>
        /// How close we have to be to the perfect size
        /// </summary>
        private const float Threshold = .5f;
        
        /// <summary>
        /// Default minimum text size
        /// </summary>
        private const float DefaultMinTextSize = 10f;
        
        private Paint _textPaint;
        private float _preferredTextSize;
        
        public AutoResizeTextView(Context context) : base(context)
        {
            Initialise(context, null);
        }
        
        public AutoResizeTextView(Context context, IAttributeSet attrs) : base(context, attrs)
        {
            Initialise(context, attrs);
        }
        
        public AutoResizeTextView(Context context, IAttributeSet attrs, int defStyle) : base(context, attrs, defStyle)
        {
            Initialise(context, attrs);
        }
        
        // Default constructor override for MonoDroid
        public AutoResizeTextView(IntPtr javaReference, JniHandleOwnership transfer) : base(javaReference, transfer)
        {
            Initialise(null, null);
        }
        
        private void Initialise(Context context, IAttributeSet attrs)
        {
            _textPaint = new Paint();
            
            if (context != null && attrs != null)
            {
                var attributes = context.ObtainStyledAttributes(attrs, Resource.Styleable.AutoResizeTextView);
                MinTextSize = attributes.GetDimension(Resource.Styleable.AutoResizeTextView_minTextSize, DefaultMinTextSize);
                attributes.Recycle();
                
                _preferredTextSize = TextSize;
            }
        }
        
        /// <summary>
        /// Minimum text size in actual pixels
        /// </summary>
        public float MinTextSize { get; set; }
        
        /// <summary>
        /// Resize the text so that it fits.
        /// </summary>
        /// <param name="text">Text</param>
        /// <param name="textWidth">Width of the TextView</param>
        protected virtual void RefitText(string text, int textWidth)
        {
            if (textWidth <= 0 || string.IsNullOrWhiteSpace(text))
                return;
            
            int targetWidth = textWidth - PaddingLeft - PaddingRight;
            _textPaint.Set(this.Paint);
            
            while ((_preferredTextSize - MinTextSize) > Threshold)
            {
                float size = (_preferredTextSize + MinTextSize) / 2f;
                _textPaint.TextSize = size;
                
                if (_textPaint.MeasureText(text) >= targetWidth)
                    _preferredTextSize = size; // Too big
                else
                    MinTextSize = size; // Too small
            }
            
            SetTextSize(ComplexUnitType.Px, MinTextSize);
        }
        
        protected override void OnTextChanged(Java.Lang.ICharSequence text, int start, int before, int after)
        {
            base.OnTextChanged(text, start, before, after);
            
            RefitText(text.ToString(), Width);
        }
        
        protected override void OnSizeChanged(int w, int h, int oldw, int oldh)
        {
            base.OnSizeChanged(w, h, oldw, oldh);
            
            if (w != oldw)
                RefitText(Text, Width);
        }
    }
}
Jan 182013
 

This problem is due to the case sensitivity of the iPhone device. The splash screen must be named ‘Default.png’, capital D included. Once you’ve renamed the file you need to remove the app from your device; you also need to go into the project folder and delete everything within the ‘Build’ folder.

 Posted by at 22:46  Tagged with:
Jan 182013
 

If you’re developing a theme for Moodle 2, you probably want to support the new custom menu functionality. Problem is it uses YUI3 to make the menu ‘work’ rather than CSS alone. This means it’s a) Harder to style and b) results in a nasty ‘jump’ as the JS kicks in – you have to style both pre- and post- JS menu. Instead why not just output a normal nested unordered list and use CSS to provide the functionality? Well, you can! You need to add a little PHP first though. Create a file ‘renderers.php’ in your theme directory and add this code (make sure to change <theme name> to the name of your theme):

<?php
class theme_<theme name>_core_renderer extends core_renderer
{
    /**
     * Renders a custom menu object
     *
     * @staticvar int $menucount
     * @param custom_menu $menu
     * @return string
     */
    protected function render_custom_menu(custom_menu $menu) {
        static $menucount = 0;
        // If the menu has no children return an empty string
        if (!$menu->has_children()) {
            return '';
        }
        // Increment the menu count. This is used for ID's that get worked with
        // in JavaScript as is essential
        $menucount++;
        $content .= html_writer::start_tag('ul', array('class'=>'custommenu'));
        // Render each child
        foreach ($menu->get_children() as $item) {
            $content .= $this->render_custom_menu_item($item);
        }
        // Close the open tags
        $content .= html_writer::end_tag('ul');
        // Return the custom menu
        return $content;
    }
    /**
     * Renders a custom menu node as part of a submenu
     *
     * @see render_custom_menu()
     *
     * @staticvar int $submenucount
     * @param custom_menu_item $menunode
     * @return string
     */
    protected function render_custom_menu_item(custom_menu_item $menunode) {
        // Required to ensure we get unique trackable id's
        static $submenucount = 0;
        if ($menunode->has_children()) {
            // If the child has menus render it as a sub menu
            $submenucount++;
            $content = html_writer::start_tag('li');
            if ($menunode->get_url() !== null) {
                $url = $menunode->get_url();
            } else {
                $url = '#cm_submenu_'.$submenucount;
            }
            $content .= html_writer::link($url, $menunode->get_text(), array('title'=>$menunode->get_title()));
            $content .= html_writer::start_tag('ul');
            foreach ($menunode->get_children() as $menunode) {
                $content .= $this->render_custom_menu_item($menunode);
            }
            $content .= html_writer::end_tag('ul');
            $content .= html_writer::end_tag('li');
        } else {
            // The node doesn't have children so produce a final menuitem
            $content = html_writer::start_tag('li');
            if ($menunode->get_url() !== null) {
                $url = $menunode->get_url();
            } else {
                $url = '#';
            }
            $content .= html_writer::link($url, $menunode->get_text(), array('title'=>$menunode->get_title()));
            $content .= html_writer::end_tag('li');
        }
        // Return the sub menu
        return $content;
    }
}
?>

Then go into your config.php file and make sure $THEME->rendererfactory is set like so:

$THEME->rendererfactory = 'theme_overridden_renderer_factory';

And now you should have nice plain HTML output ready for styling the proper way!

Jan 182013
 

Chances are you want to have slightly different content for the home page of your WordPress blog. In theory it should be easy enough, use is_home() or is_front_page(). Sadly these methods are hit and miss to say the least. Instead try using:

if ($_SERVER["REQUEST_URI"] == '/' || $_SERVER["REQUEST_URI"] == '/index.php')
{
    // Your home page specific code here
}

It’s not ideal, but it works.

Jan 182013
 

[ENV] b0 Your server does not have the mime_magic extension enabled. Mahara may have trouble detecting file types.

Getting that error? You need to enable or install the fileinfo extension. If you’re on Windows, open up the php.ini file and uncomment:

extension=php_fileinfo.dll

You can now install Mahara! The mime_magic extension is no longer available in new versions of PHP.

 Posted by at 22:34  Tagged with: