Creating a round button in Xamarin Forms

For a Xamarin Forms app I’m currently working on I wanted to have round buttons. This should normally be pretty easy, by defining a style in your App.xaml:

<Style x:Key="PrimaryButtonStyle" TargetType="Button">
    <Setter Property="BackgroundColor" Value="Transparent" />
    <Setter Property="BorderColor" Value="White" />
    <Setter Property="TextColor" Value="White" />
    <Setter Property="BorderWidth" Value="1" />
    <Setter Property="WidthRequest" Value="50" />
    <Setter Property="HeightRequest" Value="50" />
    <Setter Property="BorderRadius" Value="25" />
</Style>

When you use this style for a button, it works great on iOS and the Universal Windows Platform, but it didn’t work on Android. The problem seems to be that our app inherits the new FormsAppCompatActivity. The included compatibility button renderer however ignores the BorderRadius property.

After searching for hours, the solution turned out to be pretty simple. By creating a custom button renderer and inheriting the default, it overrides the compatibility renderer and the round button works on Android:

[assembly: ExportRenderer(typeof(Button), typeof(Project.Droid.RoundButtonRenderer))]

namespace Project.Droid
{
    /// <summary>
    /// Overrides AppCompat problems with round buttons. Works like a charm!
    /// </summary>
    public class RoundButtonRenderer : ButtonRenderer
    {
        protected override void OnDraw(Android.Graphics.Canvas canvas)
        {
            base.OnDraw(canvas);
        }

        protected override void OnElementChanged(ElementChangedEventArgs<Button> e)
        {
            base.OnElementChanged(e);
        }
    }
}

Credits to the answer on Stack Overflow here: http://stackoverflow.com/questions/38478596/how-to-remove-the-shadow-of-a-button-on-xamarin-forms

EF Core Tip 1: Running your migrations when publishing

I was looking for a way to automatically update the database after a deploy. The only way I found so far to do this, is to do this in code in your Startup class.

In the Configure method, use this code to upgrade your database other than Development:

if(!env.IsDevelopment())
{
    db.Database.Migrate();
}

If you make sure to set the correct environment variable in the environment you’re deploying to, it will upgrade the database with your migrations.

ASP.NET Core Tip 1: Setting the environment in an Azure App Service

In ASP.NET Core there is a great new way to indicate what environment your site is running on. An environment variable has been introduced called ASPNETCORE_ENVIRONMENT. You can find the official documentation here.

Here’s how you set the environment on an Azure App Service. Select the App Service you want to configure, and scroll down to Application Settings.

Under the section App Settings, you can add or update the ASPNETCORE_ENVIRONMENT setting to the correct value. Here it is configured to have Staging as the value.

Show your version number in ASP.NET Core in 2 steps

I always find it useful when working on a project to be able to see the version number of the product somewhere. This doesn’t necessarily have to be shown to the end user later on, but when you’re deploying very often I find it very helpful.

Step 1: set your current version number

  • Right-click on your ASP.NET core web project, and select Properties
  • Go to the Package tab
  • Change the Package Version variable to the version you want
  • Save the properties, and Build the project

Step 2: Show the version number in your web application

Choose the place where you want to show your version number. You can use the following Razor code to show the version:

@Microsoft.Extensions.PlatformAbstractions.PlatformServices.Default.Application.ApplicationVersion

Podcast Review: Noah Kagan Presents

I’m always weary to add another site or podcast to my list. I’ve only got so much time to read or listen, so I try to only add really good sources.

I must admit I was a bit skeptical when I heard Noah Kagan had a new podcast. After hearing Noah advertise his podcast on the Tim Ferriss Show, I tried one episode to see if it was worth subscribing to.

The episode I chose was #10: Deep Dive on Jim Rohn’s 7 Strategies for Wealth & Happiness. I was so impressed with his podcast after listening to his episode, I subscribed at once. Some of the things you’ll learn in this episode:

  1. Use focused Goals: without a goal you will never achieve your dreams
  2. Seek knowledge
  3. Learn how to change
  4. Control your money: To have more than you’ve got, you have to become more than you are
  5. Master time
  6. Surround yourself with winners
  7. Learn how to live well

Noah has a pleasant fast-paced style of talking and has a good mix of information and opinion.

Highly Recommended.

Subscribe in iTunesSubscribe on AndroidSubscribe on Stitcher

Checkout the Podcast page including all the episode details here

 

Simple branching advice

A friend of mine asked me the following questions:

  • Are you working in different branches?
  • Are you working in the same project as other developers at the same time?

As this is a topic of much debate at most offices around the world, I’m writing my own advice here. As I work almost exclusively in Visual Studio, my experience and advice is limited to that environment, and to relatively small teams.

Here’s my rule:

Try to avoid branching at all times!

Branching always costs valuable time. It takes time merging. It takes time resolving conflicts or a bad merge. It takes time explaining how it works and what features should be implemented on what branches. It takes time keeping track of your branches.

Here’s the workflow I prefer, which avoids almost all conflicts:

  1. Write a little piece of functionality.
  2. If it works and builds, check it in.
  3. If you know your affecting other developers, be sure to communicate this to them. Then check it in.
  4. Make sure your team gets the latest source after you added a conflicting change (I’m looking at you code first migrations!).

I almost never encounter any problems using this workflow. It’s great. Even when working with more developers in one project, you shouldn’t encounter much trouble.

That said, there are 2 scenario’s when I do use branching:

  1. Feature Reviews
    When there’s a new or junior developer, I always let them work on their own branch first to implement a feature. When they are done, they create a pull request in VSTS so we can review their work together. We can discuss the code and make changes if required.
  2. Production Releases
    Once you’ve got a version in production, you have to be able to provide hotfixes for it. I do this by creating a branch for that release. When there is a critical bug, it can be fixed on that branch. If applicable the fix can be merged back into the main branch. Creating a branch for each release you need to support and developing further on the main branch keeps the merges as limited as possible.

Pragmatic unit testing with Entity Framework 6

 

In my current project, we were first using a lot of mocking to be able to unit test. This resulted in a very time-consuming way of writing unit tests. After reading a blog post of Richard Garside, this got a whole lot easier.

The idea is simple, we provide a new implementation for DbSet that uses an in-memory store. Using this approach, we can use all the usual methods in a normal way without mocking all of them. We already had an interface for our DbContext, because we use Autofac for dependency injection.

Our DbContext interface

public interface IMyEntities
{
    IDbSet MyEntities { get; set; }    

    void Commit();

    void Dispose();

    void SetModified(object entity);

    System.Data.Entity.IDbSet<TEntity> Set() where TEntity : class;
}

Our actual DbContext implementation
The actual implementation of the DbContext implements the interface, so we can easily provide another implementation for our unit tests:

public class MyEntities : DbContext, IMyEntities
{
    public IDbSet MyEntities { get; set; }

    public virtual void Commit()
    {
        base.SaveChanges();
    }

    public IDbSet<T> Set<T>() where T : class
    {
        return base.Set<T>();
    }

    public void SetModified(object entity)
    {
        Entry(entity).State = EntityState.Modified;
    }
}

In-memory DbContext implementation
The implementation of our in-memory DbSet is displayed below. In the constructor, we set each entity set we use to a specific Fake implementation. We will get to that in a bit.

public class FakeMyEntities : DbContext, IMyEntities
{
    public FakeMyEntities()
    {
        MyEntities = new FakePersonSet();
    }

    public IDbSet MyEntities { get; set; }

    public virtual void Commit()
    {
    }

    public IDbSet<T> Set<T>() where T : class
    {
        foreach (PropertyInfo property in typeof(FakeMyEntities).GetProperties())
        {
            if (property.PropertyType == typeof(IDbSet<T>))
                return property.GetValue(this, null) as IDbSet<T>;
        }
        throw new Exception("Type collection not found");
    }

    public void SetModified(object entity)
    {
    }
}

In-memory DbSet base and specific sets

The base class for all FakeDbSets looks like this:

public class FakeDbSet<T> : IDbSet<T>
    where T : class
    {
        HashSet<T> _data;
        IQueryable _query;

        public FakeDbSet()
        {
            _data = new HashSet<T>();
            _query = _data.AsQueryable();
        }

        public virtual T Find(params object[] keyValues)
        {
            throw new NotImplementedException("Create a Fake(object)Set in Pegasus.Tests.Infrastructure.FakeSet");
        }

        public T Add(T item)
        {
            _data.Add(item);
            return item;
        }

        public T Remove(T item)
        {
            _data.Remove(item);
            return item;
        }

        public T Attach(T item)
        {
            _data.Add(item);
            return item;
        }
        public T Detach(T item)
        {
            _data.Remove(item);
            return item;
        }
        Type IQueryable.ElementType
        {
            get { return _query.ElementType; }
        }
        System.Linq.Expressions.Expression IQueryable.Expression
        {
            get { return _query.Expression; }
        }

        IQueryProvider IQueryable.Provider
        {
            get { return _query.Provider; }
        }
        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return _data.GetEnumerator();
        }
        IEnumerator<T> IEnumerable<T>.GetEnumerator()
        {
            return _data.GetEnumerator();
        }

        public TDerivedEntity Create() where TDerivedEntity : class, T
        {
            throw new NotImplementedException("Derive from FakeDbSet and override Create");
        }

        public T Create()
        {
            throw new NotImplementedException("Derive from FakeDbSet and override Create");
        }

        public System.Collections.ObjectModel.ObservableCollection<T> Local
        {
            get { throw new NotImplementedException("Derive from FakeDbSet and override Local"); }
        }
    }

All we have to do now for each entity set, is to create a FakeDbSet and implement the Find method, as the primary key can be different for each Model object.

public class FakePersonSet : FakeDbSet
    {
        public override Order Find(params object[] keyValues)
        {
            return this.SingleOrDefault(e => e.SocialSecurityNumber == Convert.ToInt32(keyValues.Single()));
        }
    }

Now you just have to make sure that your unit tests use the FakeDbContext instead of the real one, and your code will just work. It requires a bit of setup, but once this works, writing your unit tests is a lot easier.

 

GTD in Evernote

Bij de implementatie van Getting Things Done (GTD) kwam ik al snel uit bij het selecteren van een tool. Ga ik de lijstjes op papier bijhouden, of toch een applicatie? Ga ik prive en zakelijk mixen, of net niet? Zet ik mijn lijstjes in outlook, of toch todoist, remember the milk, of evernote?

Sinds ik het Getting Things Done boek van David Allen in mijn handen kreeg heb ik talloze applicaties geprobeerd. Na jaren zoeken bestaat de ‘perfecte’ tool voor mij nog steeds niet, en wilde ik een langere tijd mijn energie eens steken in het proces in plaats van de tool. Ik nam  me voor om een jaar lang dezelfde applicatie voor mijn GTD proces te gebruiken.

Mijn keuze is toen gevallen op Evernote. Evernote is niet direct een taakapplicatie, maar kan er wel voor gebruikt worden. Evernote is een zeer flexibele applicatie, en kan dan ook op meerdere manieren gebruikt worden voor het GTD proces. Deze post toont kort de mogelijke manieren om Evernote als GTD tool te gebruiken.

Tags of notebooks?

Een GTD implementatie in Evernote kan op verschillende manieren:

  • Notebooks gebruiken (in combinatie met notebook stacks) voor lijstjes
  • Tags gebruiken voor lijstjes
  • Een combinatie van beiden

Notebooks

Notebooks gebruiken in Evernote voor je actielijstjes ziet er bijvoorbeeld zo uit:

EvernoteNotebooks

De bekende lijstjes in GTD zoals @Computer, @Calls en @Home zijn hier gebundeld in een Notebook Stack.
David Allen adviseert in zijn eigen Evernote handleiding aan om Evernote op deze manier in te richten. Dit is inderdaad de simpelste oplossing, vooral als je niet bekend bent met de tagging functionaliteit in Evernote.

Tagging

Een aanpak genaamd The Secret Weapon bied een geheel andere aanpak. Deze opzet gebruikt 1 notebook en werkt volledig met een gelaagde tag structuur. Veel aanhangers van Evernote zweren bij taggen, deze implementatie past hier een stuk beter bij. Op de site staan diverse filmpjes die je laten zien hoe je je systeem kunt inrichten.

EvernoteTags

Wat is nu beter?

Uiteindelijk gaat het om wat voor jou fijner aanvoelt. Ik heb ze beiden geprobeerd, momenteel gebruik ik de simpelere notebook aanpa weer. Beide inrichtingen werken echter prima. Op een mobiel device kan het zijn dat beide inrichtingen wel net iets anders weergegeven worden, dit ligt een beetje aan het mobiele platform dat je gebruikt. Als je nieuw bent in Evernote, is de eerste aanpak wat laagdrempeliger om mee te beginnen, en kun je later eens wat tags gaan gebruiken om te kijken hoe dat werkt. Het is echter geheel persoonlijk.