Avoid extracting internal libraries

In a not-too-small software development company it’s very likely that you’ll manage multiple projects over time, with multiple teams and doing work for multiple customers. And for each platform/framework that you’d target (sometimes even cross-platform) you will probably determine that you could extract and reuse common components from code written by your developers in multiple ways:

  1. By extracting common components inside an application only, to better organize and maintain code for that specific project;
  2. Packaging some components to be reused by the same team and/or other teams in the company, for the same and/or other customers/partners;
  3. Publishing generic components as separate products that you could either sell or give for free to other developers too, with or without opening the source code.

I totally agree that points 1 and 3 are very good choices.

However, I think that packaging some components and distributing them only internally in your company, especially if this is done to be reused by other teams, is not a good approach, and this is for two simple reasons:

  • When you share code internally only, you tend to document it poorly, if you do it at all. Moreover, although for developers the code is the best documentation of itself, sometimes it’s difficult for colleagues to reach the original source code of such internal components or it would require asking many questions and obtaining appropriate rights to get to it;
  • When you share code internally in a company, you must ensure that the colleagues who could use it – including the newly hired developers from your and other teams – would know about what’s available and how to use the extracted common components correctly; as at first they only have knowledge and skills for the core platform(s)/framework(s) that your components rely on too, you’ll need to train them well before they could do work on top of the super-framework solution.

What to do then? You cannot just let all teams in your company to rewrite the common things (like a generic .NET unit of work/repository pattern implementation, for example) all the time, can you?

I’d say, why not? If the customers pay separately, then it’s fine – because each implementation will probably have something specific that will fit better for the needs of the customer who requested it or those of the project that it is reimplemented for!

And if you still say it’s not OK, then just go with point 3 instead, and extract a separate product out of the common code – a generic component library – that other developers could download and for which you’ll surely prepare good documentation, usage samples, and better overall quality. Of course, if legal agreements require it, talk to your customer(s) to allow you to extract, publish/sell that library separately, providing some of the outcome to the customer(s) themselves if the cost is shared as well!

Advertisements
Posted in Architecture | Tagged , , , | Leave a comment

What to do in IT

You’ve studied computer sciences, and you’re good at it. How do you select your job?

Assuming that you don’t want to be a researcher (but up to a point even if you do), and that you like software development, you can use the sheet published in this previous post to find the right place for you. Of course, some of these technologies may look obsolete, others too platform-specific, but use the sheet just to select an abstraction degree:

Technology

Nowadays, I think the best shots you have are these:

  • mobile (iOS/Android+WebAPI): easy path, high productivity, not requiring maths/physics; you’ll be able to get customers soon as everyone has a smartphone;
  • augmented reality: may require 3D maths/frameworks, oriented towards the near future; some AR apps may already run on devices today (HoloLens, ARKit, ARCore);
  • artificial intelligence: business oriented projects on core AI topics have started to appear and on such a topic you’d get a chance to work on something difficult, while integration of existing services is already possible (Microsoft, AppleGoogle);
  • quantum computing: this seem the most advanced thing you can work on today; but it would require very good maths/physics knowledge and skills because the technology has not yet reached a point where you could abstract away the details.
Posted in Miscellaneous | Tagged , , , , | Leave a comment

Cherry picking through a middle branch

Let’s assume we work with git on our project. And that we have two important branches:

  • dev – which is built and deployed automatically to a local environment;
  • master – which is built and deployed automatically to production environment.

Moreover, let’s assume we build an API, and there are also client app developers in our team working on their own projects, relying on our code deployed local environment. Finally, the system tests are done on the client apps, and when they complete, we do a pull request to merge code from dev to master due to internal way of working rules.

We will probably have many user stories to resolve, and we’ll bring them to the dev branch and the local environment upon development. But sometimes user stories cannot be merged to the master branch and deployed to production in the same order, due to any of many possible reasons, yet a pull request implies a full merge from dev branch to master. What can we do in this case?

A possible solution is this:

  • Create a middle dev-completed branch from master (it may have any other name if we think it would be better and it can be either permanent or temporary);
  • Cherry pick the selected commits – i.e. those bound to the completed user stories – from dev to dev-completed;
  • Push dev-completed branch;
  • Finally, create a pull request from the dev-completed branch (instead of dev) to master!

Update: I’ve extracted detailed instructions for the steps to perform here.

Posted in Development | Tagged , , , , | Leave a comment

DataGridComboBoxColumn.ItemsSource binding issue

The code below doesn’t work as one would expect, i.e. to allow selecting one value for each item in the DataGrid using ComboBoxes in a secondary column, even if if there is an AvailableValues property in the Window container class as the code implies:

<DataGrid ItemsSource="{Binding Items}" AutoGenerateColumns="False">
  <DataGrid.Columns>
    <DataGridTextColumn Header="Item" 
                        Binding="{Binding Name}"/>
    <DataGridComboBoxColumn Header="Value" 
                            ItemsSource="{Binding AvailableValues, RelativeSource={RelativeSource Window}}"/>
  </DataGrid.Columns>
</DataGrid>

There is a way to resolve the issue with ease, however (i.e. without any code behind hacks) – discovered here. The ElementStyle property setter for the column (and EditingElementStyle as well if the column is not read only) must be defined pointing to a style that initializes ItemsSource directly on the generated ComboBox elements instead:

<DataGrid ItemsSource="{Binding Items}" AutoGenerateColumns="False">
  <DataGrid.Resources>
    <Style x:Key="ValueComboBoxStyle" TargetType="ComboBox">
      <Setter Property="ItemsSource" Value="{Binding Path=AvailableValues, RelativeSource={RelativeSource AncestorType=Window}}"/>
    </Style>
  </DataGrid.Resource>
  <DataGrid.Columns>
    <DataGridTextColumn Header="Item" 
                        Binding="{Binding Name}"/>
    <DataGridComboBoxColumn Header="SelectedValue"
                            ElementStyle="{StaticResource ValueComboBoxStyle}"
                            EditingElementStyle="{StaticResource ValueComboBoxStyle}"/>
  </DataGrid.Columns>
</DataGrid>
Posted in WPF | Tagged , , , | Leave a comment

XAML element properties and cut-paste refactoring

As you know, to set properties for WPF objects in XAML, one uses either attributes or elements, like the Text and LayoutTransform properties of the TextBox element below, respectively:

<Border>
  <TextBlock Text="Hello!">
    <TextBlock.LayoutTransform>
      <ScaleTransform ScaleY="2"/>
    </TextBlock.LayoutTransform>
  </TextBlock>
</Border>

Using elements is required when the content to set as property value is complex (and cannot be expressed with a simple attribute) and it is also local (i.e. there are no reasons to transform it into a resource), such as the case of the LayoutTransform setting above.

However, many times XAML is refactored during the lifetime of a project, and requirements like this appear often: the Hello text block should be replaced by a TextBox when the app enters edit mode, so that the end user can change the text at will.

To address this, you would probably update the XAML to something like this:

<Border>
  <Grid>
    <TextBlock Text="Hello!" Visibility="{Binding IsReadOnly, Converter={StaticResource BooleanToVisibilityConverter}}">
      <TextBlock.LayoutTransform>
        <ScaleTransform ScaleY="2"/>
      </TextBlock.LayoutTransform>
    </TextBlock>
    <TextBox Text="{Binding Text, ElementName=TextBlock}" Visibility="{Binding IsEditing, Converter={StaticResource BooleanToVisibilityConverter}}"/>
  </Grid>
</Border>

Of course, this works assuming that you have prepared IsReadOnly and IsEditing properties under data context (e.g. view model), and surely there are easier ways (such as triggers) to do this, but for now let’s focus on the original LayoutTransform setting. In the updated code, it applies only to the TextBlock, but not to the TextBox, so the look of the text will change when entering edit mode. Not good!

To resolve the problem, you need to move the ScaleTransform definition to the LayoutTransform property of the element that contains both the TextBlock and the TextBox, which is the new Grid element that you introduced to ensure that the two text elements are on top of each other, i.e. same grid row and column, zero and zero, since a Border cannot have multiple children (and you needed a Panel, e.g. Grid):

<Border>
  <Grid>
    <Grid.LayoutTransform>
      <ScaleTransform ScaleY="2"/>
    </Grid.LayoutTransform>
    <TextBlock Text="Hello!" Visibility="{Binding IsReadOnly, Converter={StaticResource BooleanToVisibilityConverter}}"/>
    <TextBox Text="{Binding Text, ElementName=TextBlock}" Visibility="{Binding IsEditing, Converter={StaticResource BooleanToVisibilityConverter}}"/>
  </Grid>
</Border>

But as you can see in the updated example, the property element needs to be updated, i.e. the prefix class needs to be changed from TextBlock to Grid, so the refactoring is not an easy cut and paste operation! Imagine this repeats for multiple properties and multiple locations within the XAML.

To avoid the required prefix changes, however, you could have used this simple tip from the beginning:

When setting WPF properties using XAML elements, use a base class prefix.

In our example, that means that we could use <FrameworkElement.LayoutTransform> instead of <TextBlock.LayoutTransform> originally, since TextBlock inherits, at some point in the hierarchy, from FrameworkElement, and then we could easily move the definition from the TextBlock to the root Grid with a simple cut-paste operation because the Grid is also a FrameworkElement itself – both examples below work correctly:

<TextBlock ...>
  <FrameworkElement.LayoutTransform>
    <ScaleTransform ScaleY="2"/>
  </FrameworkElement.LayoutTransform>
</TextBlock>
<Grid ...>
  <FrameworkElement.LayoutTransform>
    <ScaleTransform ScaleY="2"/>   
  </FrameworkElement.LayoutTransform>
  ...
</Grid>

And now you just need to know good base classes for the objects you set up in XAML. Although the WPF class hierarchy seems (and is) complex, remember that most of the times FrameworkElement is the one you can use for most common properties where you would want to support cut-paste refactoring (interchangeability).

Posted in WPF | Tagged , , , , , , | Leave a comment

Developer, you need an iPhone

I don’t mean iPhone X: it probably doesn’t worth its price, although benchmarks shock. And I don’t mean 8 unless you want wireless charging and a little more power. It can surely be just an iPhone 7, especially if you like black. It can also be 6S if you accept an older chip and a model that is not water/dust proof, or even an SE if you can live with a smaller and less colorful screen, and don’t want 3D touch either. Compare models here.

But if you’re a UI app developer today you do need an iPhone, and here are the reasons, in a logical order, as much as I could find it:

  • People go mobile, and many go mobile-only, while desktops fade away. Asia is first, followed by the Americas, but Europe also joins the trend.
  • With the unfortunate Windows Mobile failure, even with free Xamarin, Windows is doomed to remain a server side OS, eventually buried in Azure services, and if Microsoft follows its current plan (as it seems) of remaining a services-only company, Linux may eat it there too: they just released .NET Core 2.0. While they continue selling Office 365 and Azure, which I assume is their best shot to remain relevant in the IT world for the medium term, they seem to have problems with HoloLens; some time ago I considered their holographic device that is capable of running most 2D UWP apps too as a possible Windows saver; but not anymore, because from my point of view they should have already prepared something for the end user by now, and instead I see no advance at all on that side.
  • Android and iOS will soon be the only ones that matter, even for AR (see ARCore and ARKit). And even for many businesses, not only for consumers. UI app developers (need to) accept it. Even if they come from the beloved Microsoft ecosystem of around 2010, like I do.
  • End users seem to like native apps more than Web apps, so going HTML5 and JavaScript won’t be the best choice. (I changed my mind, indeed; a few years ago I would have advocate towards using JavaScript everywhere.) But of course, a presentation Web site will always be needed for your company and products.
  • To be able to test your Web sites on the appropriate browsers, even if only those made for presenting your products, you need to check the browser market shares. Google Chrome is a must, but note that the second place is won by Apple‘s Safari. And devices that run it are only Apple devices: iPhone, iPad, and Mac. As it’s no longer available nor supported on the Windows desktop.
  • Back to native development, we can easily find out that Android has a high market share, but also that iOS app sales are often of higher value (especially for business-oriented apps) since iOS devices seem to be the preferred devices among those who afford them.
  • Therefore, to be relevant as an app developer, you should develop both for Android and iOS; the latter still has an appreciable share of over 20% on the phone market, and for tablets it even passes 60% (tablets are a niche, at this time, themselves, but they are still important.)
  • Targeting both Android and iOS apps, developers often dismiss cross-platform frameworks (both those producing native output like the above mentioned Xamarin or building JavaScript-enabled WebView-based apps like Cordova and Ionic), even that they could help reuse much code, mostly because they are late in feature adoption compared to the first party native development tools provided by Google and Apple, corner cases are way more difficult to resolve when they (inevitably) get you around, and (for JavaScript targets) app performance may be too low.
  • However, even if you would choose Xamarin or Cordova, you will need a Mac to be able to deploy iOS apps, besides an Apple developer subscription. And of course, if you choose to develop in a fully native fashion, you’ll also use xCode on that Mac.
  • For Android app development, things are easier: you can develop natively with Android Studio or Xamarin either on your old Windows PC or on the Mac (Microsoft also released Visual Studio for Mac that includes Xamarin!) And to release your apps you just need to register as an Android developer with your Google account (with a one time payment).
  • But when you develop mobile apps it’s quite mandatory to test your code on real devices running each of the target platforms, and not only on simulators. So you’ll need at least one iPhone and one Android phone since you target both their OSes.
  • If you’re a freelancer, a small business owner, or just bring your own devices into a company domain to work for that employer, and use them both for personal stuff and for business, it will be easier if one of the two phones will be your primary mobile machine. And as you’re a geek, that really needs to be the a powerful one, and therefore it’s probably going to be the most expensive of the two. That means you will either get a recent iPhone if you decide for iOS as primary device’s OS or a Google Pixel phone, or a similarly expensive third party device if you want Android.
  • Thinking about the secondary device, assuming that you don’t want second-hand items, you’ll notice that the least expensive iPhone at this time is the SE, but it’s still quite expensive and also maybe too powerful compared to many Android phones that you could use for testing your apps as secondary devices. For example, a new, but less powerful Samsung Galaxy J3 is only half of the price of an iPhone SE.
  • To conclude, as you need two phones – one with state-of-the-art technology and one for testing purposes only – you need to sum up their prices. And I really think that the amount is going to be much lower if you get a powerful iPhone and a low cost Android. This will also be a good simulation of the real world, where many of the Android phones are lower cost devices and run older OS versions, which your app should still support, while most iPhones are more recent and capable, as Apple pushes them hard towards its (smaller, but richer) crowd.

Note: iPhones (and Macs) are not only style & fashion devices, like I used to think myself, and like others may still think due to rumors and misunderstandings; they are really powerful devices and Apple hardware and software teams really seem to collaborate well, as software innovation easily turns into interesting hardware changes whenever needed. This integration is most of the times more important than having the newest hardware or the newest software installed, if they are obtained separately and from different parties. Moreover, Apple‘s ecosystem, although it lacks a few things on the server/cloud side, is somehow similar to Microsoft‘s old world that you may have liked.

PS: If you’re an Android fan, don’t hate me. Get yourself an Android primary device and an iPhone SE for iOS testing. You’d pay more this way, but if it brings more emotional value to you, don’t hesitate and go for it. Maximize your own value! (You’ll still need a Mac, though, and it will probably be less integrated to your primary Android phone than it would with an iPhone, but again, it’s your life, your choice.) 🙂

Posted in Development | Tagged , , | 1 Comment

Bloody space in a form input name

Suppose that you have to HTTP-post a form with some pre-computed hash field to a service. You prepare the form as HTML or as an HTTP client call, with a hidden input field or a request body parameter that is (apparently) named hash and submit it.

But you receive an error from the service, like this:

The computed hash is different than the hash in your request.

You struggle to see what’s the difference, thinking that maybe your hash generation algorithm was incorrect or incomplete and sometimes you might work for a few hours on this to only see eventually that… there was an inadvertently entered space in the name of the input field:

<input type='hidden' name='hash ' value='{computedHashValueHere}'/>

In this case the hash<space> field is correctly sent with the form, but the service might not match it to the expected hash field, and also it might not inform you that the expected hash hasn’t been received at all, especially if it’s implementation is poor (like that of ipg-online.com, for example).

And you won’t be able to easily spot the issue with a network sniffer either (e.g. Fiddler), since the space will probably be there in the view just as an (obviously) invisible char!

Lesson learned: be very, very careful and cautious when you define your request in these situations. Check for supplemental or missing spaces, lowercase vs. camelCase vs. PascalCase vs. UPPERCASE vs. ANYOtherCase, and also check that the form root element is defined correctly.

For the latter case (regarding the root form element definition), note that the example form below will only send one field – the second – feel free to try it yourself and check the form in the browser’s DOM (using developer tools) to detect the issue:

<form id='myForm' method='post' action='http://myurl.com">
  <input type='hidden' name='x' value='{x}'/>
  <input type='hidden' name='y' value='{y}'/>
  <input type='submit' value='submit'/>
</form>

Or, if you don’t have the time to do it, just check this screenshot – it will help you easily identify the incorrect ending character for the action attribute of the form definition (double quote instead of single quote):

screenshot

Posted in HTML5, WebAPI | Tagged , , , , , , | Leave a comment