One of the options for creating a Vuex module in NuxtJS is to create separate state.ts, getters.ts, mutations.ts, and actions.ts files in the module folder. Especially for large modules, this can make the code easier to navigate. However, a very important detail about this approach is mentioned very briefly in the documentation.
Posts in July 2020
Posts in June 2020
The NuxtJS application framework for Vue.js replaces a lot of the low-level configuration through conventions, e.g. routing. But what if you need access to that configuration to implement a certain feature? For example, the vuex-router-sync module watches for route changes to sync the current route with the Vuex state. How could this be done in NuxtJS?
String literal types are a lightweight alternative to string enums. With the introduction of the const assertions in TypeScript 3.4, even type guards can be implemented in a DRY manner.
Immutable objects can't change after they've been created. Because of this, all data needed for their initialization must be passed into them through the constructor. This can result in constructors with (too) many parameters. With the builder design pattern, this can be avoided.
The Moq mocking library in version 4.13.0 added support for matching generic type arguments when mocking generic methods. The documentation doesn't go into much detail but thanks to additional information in IntelliSense tooltips and the originating GitHub issue I managed to quickly resolve the no implicit reference conversion error which I encountered at first.
Posts in May 2020
The Enterprise Application Patterns using Xamarin.Forms book by David Britch is available as a free download on the Microsoft's .NET Architecture Guides website. It's a good introduction to MVVM. It can also serve as a refresher for someone with past MVVM experience who hasn't worked with Xamarin.Forms before. Although the sample code uses Xamarin.Forms, it's almost just as useful to WPF and UWP developers.
When looking for a way to quickly position an application window at an exact predefined position, I chose AutoHotkey as the best tool for the job. The ability to create a script that moves a window and assign it to a keyboard shortcut was exactly what I needed. It still required some tweaking before it worked well enough for my needs.
Although transition animations for modal pages can be customized individually for each instance of a modal page, they still can't easily affect the content of the page that's opening them. The animation factory function only gets access to the modal page that's being opened but not to the originating page.
BlurHash is a compact representation for image placeholders developed by Wolt. Implementations are available for many languages. Since TypeScript is one of them, it's easy to use in an Ionic application as well.
Although Ionic supports custom transitions when navigating between pages, I couldn't find much documentation about it. However, by combining information from different sources I managed to create one and fully understand the code involved.
Posts in April 2020
In my previous blogpost, I implemented a staggered animation in Ionic Angular where the animation-delay depended only on the position of the item in the list. This time, the delay will depend on the current scroll position of the list. The animation will start in the middle of the screen and move towards the top and bottom edges.
Recently, Josh Morony published an interesting tutorial about staggered animations in Ionic. Since he's using StencilJS, there are some syntax changes required to make his sample code work with Angular. It wasn't as trivial as I expected.
In a highly polished mobile application, there are typically many short transitions and animations. To get you started, Ionic comes with several built-in animations, such as transitions between pages, modal page transitions, reactions to clicks, etc. But sooner or later you'll want to give your application a more unique identity by customizing existing animations and adding additional ones.
Posts in March 2020
Recently, we encountered an interesting design challenge in the Ionic application we're developing: have a transparent gradient overlay on top of long scrolling text. I'm sure it's a simple task for an experienced CSS wizard but since it wasn't immediately obvious to us how to do it best, I'm sure that someone else will also benefit from our learnings.
I've been doing some Cordova plugin development recently and at some point, I've decided to add TypeScript type declarations to make the plugin easier to consume from Ionic (or other TypeScript based) applications.
I have a hard time recommending the book to anyone. Although it mostly focuses on basics, I don't think it's suitable for beginners because of how short the explanations are. For me, its value was mostly in a few random nuggets of knowledge I stumbled upon while reading.
Posts in February 2020
Recently, we discussed the behavior of Promise.finally in our development team. Even after reading the official documentation, we weren't unanimous on what will happen in certain cases. In the end, I wrote a couple of test cases to make sure about it.
Although Git can be used over HTTPS with username and password authentication, it's much more convenient to use over SSH. Now that OpenSSH client is included in Windows 10, SSH can be easily set up without any third-party clients.
Angular based routing in Ionic 4 introduces some gotchas if you're used to navigation in Ionic 3. Reinitializing the navigation stack by setting the root to the same page as it was before is one of those gotchas.
Since the introduction of GitHub Actions there's often no need any more to use an external CI/CD service. After I moved my blog repository from BitBucket to GitHub it was time to move my continuous deployment configuration from CircleCI to GitHub Actions as well.
Posts in January 2020
The Safari browser has a tendency to render pages differently than Chrome. Troubleshooting such cases in Ionic apps and testing potential fixes can be time consuming, especially when developing on Windows. Building the app on the build server and having it deployed via TestFlight can make the feedback loop really long. I managed to make it shorter by opening the page served from my development machine in the mobile Safari browser.
I can strongly recommend the book to any software developer, no matter his level of experience. Junior developers will learn about techniques that will help them do their job better. Senior developers will probably already know about most of these techniques but will have a great opportunity to consider their importance as they are reminded about them while reading the book.
With the SportTracks 3 end of life just around the corner and no assurances that the application will still work after that, it's time to export old data from it and start using other applications and services. While the application makes it easy to export activity data, there doesn't seem to be any built-in feature for exporting the weight data.
After getting asset loading working in Ionic unit tests, I wanted to also test the error handling in case an asset fails to load. Mocking the fetch call would be the easiest way to do that.
One of the less talked about new features in C# 8 are using declarations. That's not too surprising since it's essentially just syntactic sugar for using statements. However, the exact location in the code where an object is disposed might be different than with using statements. Since other methods might be called implicitly when an object is disposed, this might change the behavior of your code making it incorrect.
Posts in December 2019
Recently I had to embed a JSON file as an asset in my Ionic 4 project. When I tried to test the code accessing the asset, I was unpleasantly surprised. The asset failed to load with a 404 error. The body of the response was "NOT FOUND".
In Ionic 3, navigation was stack based. NavController was used for controlling the navigation stack (i.e. for pushing pages onto the stack and popping them of the stack). Fortunately, there's still a NavController in Ionic 4. It's built on top of Angular routing and makes navigation more similar to how it worked in Ionic 3.
After upgrading our Ionic application to Ionic 4, testers started reporting that the side menu randomly froze in place when an item inside it was clicked. The problem could only be resolved by restarting the application. We tracked it down to two lines of code but unfortunately we didn't have a reliable way to reproduce the issue and the code seemed perfectly valid.
In a recent discussion of pros and cons of using EF Core in-memory database provider for testing, the idea of using SQL Server Express LocalDB instead came up. I remembered reviewing an article about this last year. But after reading it once again, it turned out that some work would still be required to create a working sample.
Posts in November 2019
Support for custom transitions between pages in Ionic framework (e.g. when opening a modal page) has never been well documented. Fortunately, there are blog posts for both Ionic 3 and Ionic 4 which provide more information and can serve as a good starting point for creating your own custom transitions. But even with all that, it can be tricky to convert existing custom Ionic 3 transitions to Ionic 4 when upgrading an application.
Android hardware back button is something one can easily forget about but must in the end be properly supported in any mobile application. Unfortunately, built-in support in Ionic 4 is less than perfect. Many scenarios are still not properly supported as documented in a GitHub issue which hasn't been resolved for almost a year.
If you want to use certificate pinning in Ionic 4 applications, the Cordova Advanced HTTP plugin is your best option. There's even an Ionic Native wrapper available for it to make it easier to use. In this post I'm focusing on how to put the certificates into the output folder as required by the certificate pinning functionality despite that folder being deleted at the beginning of every build.
In Ionic 3, there was no need to pay any attention which pages you navigate to and how. This made it easy to create pages for navigating hierarchical structure, e.g. a catalog. In Ionic 4, the same route can't repeat in the history stack.
Puzzle geocaches often require some calculations to determine the final coordinates. That's particularly common in GeoArt trails. Although some of these trails can be quite long, I had always solved them manually. Until I encountered the Pirate Cruise trails near Split in Croatia, that is. Almost 500 caches requiring geodetic calculations were too many to do by hand. I decided to find a way to automate the calculations.
Posts in October 2019
In August, I was invited by the organizers of the .NET DeveloperDays conference to have a session about C# 8 in Warsaw at the end of October. After a few exchanges with them and a short consideration, I decided to take on the challenge of speaking at a conference of such size for the first time. As promised at the end of my session there, I'm making the slides and sample code available for download.
MakeIT is the yearly conference of the local Java community. I usually don't even consider speaking there but when the call for papers was announced for this year, I was in the middle of preparing my session about microservices for Global Azure Bootcamp 2019. Since the session focused on the architectural patterns and was mostly technology agnostic, I decided to submit it for MakeIT 2019 as well.
In Ionic 4, even for lazy-loaded modal pages the component must be specified using the type. There's nothing wrong with that. Enforcing strong typing is usually a good idea. However, it can potentially cause a circular dependency, especially if you move the code for creating and opening modal pages to a separate service to avoid repeating the same boilerplate code and make testing easier.
When creating pages using the Ionic CLI, by default each one of them is placed in its own module to enable lazy loading. However, if you want to display such a page as a modal instead of navigating to it, it won't work without some modifications. Although lazy-loaded modal pages are supported in Ionic 4, the documentation isn't all that detailed about it.
Posts in September 2019
Ionic 3 provided a unified way for passing parameters to newly opened pages - the NavParams object. In the target page constructor, it could be used to get any parameters passed to that page. Ionic 4 doesn't have a universal NavParams object anymore, therefore other approaches must be used to achieve the same.
Including a hyperlink in a checkbox label is a common way to provide more information about the choice the user is making. Unfortunately, in Ionic such a hyperlink doesn't work out of the box because the whole label acts as toggle for the checkbox. There's an easy way to make it work, though.
This Tuesday, the Slovenian Developers User Group organized the annual meetup with the highest-voted sessions from the NT conference. Unfortunately, the second speaker couldn't make it back to Slovenia in time due to unforeseen circumstances. Since we couldn't find a different speeker on such a short notice my session about C# 8 was the only one at the event.
Creating a menu in Ionic 4 should be simple and the process seems to be well documented but I struggled with it longer than I should have. Therefore, I decided to share my findings for my future self and for everyone else who might find this helpful.
Posts in August 2019
Angular supports several different modes of encapsulating styles in components so that styles from one component don't affect elements in other components. By default, Angular uses ViewEncapsulation.Emulated to emulate native Shadow DOM behavior without actually using Shadow DOM. Ionic 4 uses the same default which can cause problems when upgrading applications from Ionic 3 where ViewEncapsulation.None was used.
Ionic has built-in support for navigating back using the swipe gesture. If you want to disable it for the whole application, you can pass a configuration option to IonicModule. Alternatively, you can disable and re-enable swipeback navigation ar runtime. In Ionic 3, NavController exposed a property for that. In Ionic 4, NavController doesn't provide such a property anymore. Instead, IonRouterOutlet now has an equivalent swipeGesture property.
In Ionic 4, the dismissAll method for closing all currently open loading overlays has been removed. This might not be such a bad idea since it could cause problems when used carelessly. Still, when porting an existing Ionic 3 app to Ionic 4 not having an equivalent for it available can be a problem. I created my own replacement to make porting easier and minimize the required code changes.
In Ionic 3, there was an easy way to automatically dismiss a loading overlay when the navigation to a new page completed - you only had to set the dismissOnPageChange flag when creating the overlay. There's no such flag available in Ionic 4.
Since the release of Roslyn, the complete C# compiler pipeline is available as a NuGet package and we can include it in our own application. I was wondering how difficult it would be to use it to compile some C# source code into an executable and run it.
Posts in July 2019
If you've ever used a JetBrains IDE like IntelliJ IDEA, WebStorm or Rider you might have noticed the CamelHumps option for keyboard navigation which allows you to jump by word in a camel-cased identifier instead of by the whole identifier. The same functionality ia also available in the ReSharper Visual Studio extension. When I started using Visual Studio Code regularly, this was one of the features I missed.
Some Angular directives only make sense when they are applied to a specific Angular component. For example, the host component might be injected in the directive constructor so that directive code can manipulate it.
Posts in June 2019
Last year I wrote a blog post about making code for displaying alerts reusable and testable by wrapping it into a function which returns the user's response as a promise. The sample was written in Ionic 3. The code doesn't work in Ionic 4 without modifications. Since I recently received a request for an Ionic 4 version of the code, I decided to write this follow-up post.
Even if you're not a fan of Microsoft Store, you might still be forced to use it for games which are exclusively available from there. Some of these games are rather large. This can be a problem because Microsoft Store gives you only limited control over where it will install the applications. Making them available to multiple users on the same computer can be an even greater challenge since they are installed per user.
To take full advantage of TypeScript in the Vue.js-based Hippo CMS-hosted SPA I'm working on, I configured the typescript-generator-maven-plugin to generate TypeScript interfaces for Java classes used in REST services. It worked great with classes originating from external libraries which I could add as dependencies. However, it failed with classes originating from the Hippo CMS Site module because it was compiled into a .war archive which Maven can't handle as a dependency.
Hippo CMS treats internal links differently from external ones. Even when they are a part of an HTML field in a content document, they are stored as a reference to the referred content document and not as a regular hyperlink. When you're using the hst:html tag for rendering HTML fields in the template, it will take care of that automatically. But if you want to use the raw HTML string in some other way, the internal links inside it won't be valid.
Posts in May 2019
Hippo CMS has built-in support for configuring components through auto-generated dialogs in the Channel Editor. These can easily be defined by using annotations in the component's ParametersInfo interface. Although there's an option to open a document picker, the documentation only hints at different configurations for it. After reading, it wasn't clear how to use it for picking a content folder instead of a document.
Yesterday the NT Conference 2019 concluded in Portorož. This year I had three sessions there. On Tuesday, I talked about the new language features in C# 8. On Wednesday, I repeated my session about application architecture from this year's Global Azure Bootcamp. My final session on Thursday was about global tools in .NET Core.
When creating my first Vue.js project I configured it for TypeScript support and Jest based unit testing. This might not be the most common setup but it does express my tooling preferences. To no surprise, the first component I wanted to unit test used fetch which meant I also had to use jest-fetch-mock to mock its calls. There were a couple of obstacles on the way to the first working test.
A while ago I've already written a blogpost on how to inject a different Angular service implementation based on a runtime value. With that approach, the selected service was initialized at startup and remained the same for the entire application lifetime. In response to that blogpost, I received a question how one could switch between the implementations while the application is running. This blogpost is my detailed answer to that question.
It was Global Azure Bootcamp time again last Saturday and for the third time in a row I was attending the Slovenian one as a speaker. This time, my session was not about a specific technology or tool. Instead, I dived into application architecture. The microservices hype has been my pet peeve for a while and I wanted to share my opinion about it with the attendees.
Posts in April 2019
I haven't done much PHP development, but occasionally I still need to read or write some PHP code. The latest reason for this was a CMS site for a local community organization I'm administering. I was asked to modify its template to show a different logo based on where in the sitemap the current page is located. How hard could it be?
Once a Hippo CMS project is deployed to production for the first time, editors will start changing the content there. There's no easy way to merge those changes with the ones coming from developers. The official recommendation is to use Groovy updater scripts to do that when necessary. It's possible to automatically execute these scripts on startup, but this feature is almost completely undocumented.
Posts in March 2019
In corporate environments, there's often a need for a private package manager repository where packages for internal use can be hosted. The free Nexus Repository OSS product from Sonatype is a common choice in such scenarios. Its wide range of supported repository formats includes NPM as well.
In a Hippo CMS site, all URLs are under its control. Using the sitemap configuration, you can to some extent influence how URLs will map to content but there's no obvious or well-documented way to make Hippo CMS ignore the URL and let it be processed by a different servlet.
If untrusted values are not correctly escaped when included in web page markup, they can easily make the site susceptible to attacks. To reduce the risk of developer mistakes, many template engines can take care of escaping by default. FreeMarker template engine is no exception. Unfortunately, Hippo CMS default configuration doesn't enable automatic escaping in FreeMarker templates.
Although I'm hosting my blog in Azure, I have a local instance of AWStats configured for analyzing the server logs. Since I'm only looking at the statistics a few times a year at most, I don't really need to have AWStats running all the time on my local server. What if I could just run it on demand when I need it instead? Docker seemed a perfect tool for the job.
Running user-defined scripts as scheduled tasks is the best way to backup external data to your Synology NAS. They can easily be created in the Task Scheduler pane of the Control Panel. However, there are a few important details to be aware of, especially if you're not a versed Linux user.
Posts in February 2019
The final release of Ionic 4 is a good incentive for migrating existing Ionic 2/3 applications to Ionic 4. The official documentation lists the required steps for creating a new Ionic 4 project and adding Android support to it. If you're using Cordova 8+, then the application will run fine. But if you're still using Cordova 7.1.0, you'll only be greeted by a white screen when the application starts.
The HostListener decorator can be used in Angular directives to listen to events triggered by the host element to which the directive is attached. For example, one could listen to the submit event of a form. However, this will not work for any programmatic attempts to submit a form.
After using a framework for a significant amount of time, you gain confidence that you understand it well. But you might still have incorrect assumptions which don't affect your work most of the time. I learned that about Angular recently when I wanted to handle the paste event for an input element.
Since this week, The Absolutely Awesome Book on C# and .NET is finally available for order in its final form: in all eBook formats and with the accompanying source code.
Posts in January 2019
Although I could say that I understand covariance and contravariance, I still need to pause for a moment and think it over whenever I have to deal with them. It all gets even more complicated if generic type arguments aren't directly in the role of an input parameter or a return value.
Posts in December 2018
Recently, I've been using Word a lot and became much more familiar with many of its features. In particular, I'm working with comments and other reviewing tools. To further speed up my work as I'm getting more comfortable with the commands, I wanted to start using keyboard shortcuts instead of the mouse.
Having multiple displays on a computer is a huge productivity boost for me. With two displays connected both to my dock both in the office and at home, most of my needs are covered. But for a long time, the built-in display on my laptop had to be enough while traveling. At least until I saw a friend of mine using his iPad as the second display.
Recently I received a prepaid card with a fixed amount from a reward program. I was looking for a way to spend the full amount on the card. Steam Wallet seemed to be the best option, but it doesn't support adding any amount of funds either. Here's how I managed to do it anyway.
Tuples, as added to C# 7, can be a nice alternative to anonymous types in LINQ when you only want to return a subset of values from the queried type. Before tuples, this was only possible by creating an anonymous type in the Select method. Now you can create a tuple instead. However, if you try to do that with EF Core, the code won't compile. How come?
Posts in November 2018
There's no built-in solution in EF Core for getting the SQL query that is going to be sent to the database. I could find an implementation by Nick Craver which worked fine with EF Core 2.0.0, but fails with the current version of EF Core (2.1.4). Since I really needed it for the latest version, I decided to put the effort in to make it work.
The Promise.catch method is a convenient tool for handling errors anywhere inside the promise chain up to the method call. However, care must still be taken when writing the chained code inside the Promise.then method, otherwise some errors might not be properly handled.
In Java, .properties files are by default saved in ISO-8859-1 encoding. Since many languages use characters not included in this encoding, these characters will need to be expressed using Unicode escape sequences. Fortunately, IntelliJ IDEA can automatically handle conversion between the Unicode literals and their corresponding escape sequences, but the feature is not enabled by default.
I recently started colaborating on a project which had a couple of private Maven dependencies. The project owner provided a custom Maven configuration file which routed all dependency downloads (even public ones) to their Nexus server acting as a caching proxy. I reconfigured Maven to primarily use the official public repository and only fall back to the private Nexus server for dependencies which couldn't be resolved.
Freemarker, the Hippo CMS template language, includes special directives for working with sequences. Additional built-ins can be used to get more information about the loop variable. However, I've noticed that they don't always work.
Posts in October 2018
In Hippo CMS, a page is generated from a hierarchy of Freemarker templates. Child contents can inject content into other parts of the root page using head contributions. In this post, I'm listing some restrictions which apply when using them.
One could argue that a JSON REST service should never return an empty body, but you might not always have a say in how a service you need to call will behave. Unfortunately, CRISP API in Hippo CMS throws a NullPointerException if the response body is empty.
The recommended way for integrating external services in Hippo CMS is the CRISP API. The official documentation provides detailed enough instructions for installing, configuring and using it. However, when I needed to customize the default Jackson ObjectMapper, it wasn't all that obvious how I could do it.
In Log4j, Mapped Diagnostic Context (MDC) can be used to provide additional context information for every log message. In server applications it will usually be initialized for every request in a filter. In Hippo CMS, a custom valve must be injected into the request pipeline for that purpose.
Posts in September 2018
If you want to post-process the application logs, using the JSON format will usually make it easier. In Log4j, there's the JSON Layout available for that purpose. Making it work in Hippo CMS took me longer than expected.
Interpolated strings in C# 6 introduced a simplified syntax for most use cases of String.Format. The new syntax has several immediate advantages, but its internal implementation also lends itself to some innovative usage. In EF Core 2.0, interpolated strings can be used to write safe SQL queries with shorter syntax. Let's take a look at how this is implemented.
There's a lot of flexibility in type conversions in C#. On top of built-in implicit and explicit conversions, you can also define custom conversions. However, you might not be aware that these are not supported for interfaces.
Generating the proxy client classes for a web service is only the first step. While the official documentation includes a basic sample for invoking a method on the web service, I had a hard time finding any guidance on how to pass in the credentials for basic authentication.
Posts in August 2018
Apache CXF is a common choice for calling SOAP web services from Java. It's most convenient to use when you generate proxy client classes from the web service WSDL file. There's a command line tool available for that but if you don't want to put the generated sources in source control, you'll probably prefer the Maven plugin.
There are lots of components included with Ionic framework, but not many of them can be used inside a Navbar. Fortunately, with some resourcefulness, it's easy enough to create a solution of your own by combining together multiple built-in components.
Cordova plugins can use variables for project specific values which must be entered when installing them. When these variables are used in Gradle build files for Android, a bug in Cordova 6.5.0 can cause the build to fail.
Updating of views in Angular is fully dependent on its change detection. I've already written a post on how code executed outside NgZone can be missed by change detection. But Angular's highly optimized change detection code can bite you in other scenarios as well. If it determines that the same value has been assigned, it doesn't propagate the change which can break intended functionality.
Posts in July 2018
When you want to reuse a part of markup in Angular, you usually wrap it into a separate component. However, sometimes a component can be an overkill. You might have only a couple of lines of markup which you need to repeat in multiple places inside a single component but nowhere else. In that case, embedded templates could be just the right tool for the job.
If you're developing applications for Ionic or Angular, you have probably already encountered static forRoot() and forChild() methods which you need to call when importing other modules, such as ngx-translate. You might not be fully aware of their significance, but when developing your own shared modules, you'll likely need to learn more about them.
Surprisingly, there's no easy to use functionality built into Ionic to find a specific page in the navigation stack by its name and pop as many pages as necessary to reach it. Fortunately it's not too difficult to implement this on our own, thanks to the undocumented popTo method in NavController.
Cyclomatic complexity is a simple code metric, commonly used to identify complex methods which are difficult to maintain and therefore good candidates for refactoring. It is one of the five code metrics built into Visual Studio 2017, but it isn't available for .NET Core and .NET Standard projects. Let's look at third party extensions which you can use instead.
Posts in June 2018
In the previous blogpost, I created a wrapper function for creating an alert in Ionic which returned a promise with user's input. Although alerts in Ionic are quite flexible, you'll eventually need to use a modal page instead of an alert. There's no reason why modals couldn't be wrapped into a function in a similar manner.
Alerts are a great way for collecting simple inputs from the user with minimum effort. The examples in the official documentation contain business logic directly in button handlers. Wouldn't it be more convenient if the code for displaying the alert could be wrapped in a separate function returning the value entered by the user?
In a previous blogpost, I've described how to intercept console log output when the application is running on the device, so that it can later be exported using the standard sharing functionality. Although this is usually the most convenient approach for testers, it's an overkill during development. In such a scenario, it's more effective to look at the console output from the debugger.
Quick switching between tabs in Ionic can cause issues when one of the tabs requires a long initialization process every time it is displayed, as for example native Google Maps do. Before the initialization is completed, the user might already leave the tab and then navigate back to it, triggering another initialization in parallel to the first one. One way to avoid the issue is by disabling the switching between tabs until the page initialization is complete.
Posts in May 2018
It's the week of NT Conference 2018. I had two sessions this year. On Tuesday, I talked about a selection of common C# gotchas which can surprise even an experienced C# developer. In my second session, I explained the benefits of continuous testing and showed how to configure it for a .NET Core project in Visual Studio 2017 and Visual Studio Code.
Ionic Generate command is a handy tool for creating new pages, components, providers and other file types in Ionic applications. It strongly relies on the standard Ionic project structure. Since the recommended project structure has changed quite a lot since the initial release of Ionic 2, the command might not work as expected on older projects if their structure has not been kept up-to-date.
Lazy loading was introduced in Ionic 3 to reduce application startup time. It started out as an experimental feature, but has since then become the default way for building Ionic applications. However, even with lazy loading enabled, application performance can be tweaked further with different configurations options.
In one of my previous posts, I've written about changing the config.xml file when building an app for different environments. However, sometimes that's not enough. You might want to make other changes in the application which are only possible in code, e.g. have a different tracking ID for Google Analytics or allow sharing the console log.
Posts in April 2018
It's April again and last Saturday it was time for the annual Global Azure Bootcamp event. The Slovenian one was taking place at the local Microsoft offices. In my session, I explained how to configure Visual Studio Code to improve the experience of .NET Core development as much as possible.
Modal and regular pages are very similar in Ionic. When using lazy loading their name must be passed to the controller instead of their type, otherwise they will fail to open. However, with module preloading enabled, this issue might sometimes not manifest itself.
After we upgraded the Cordova version on our build server from 6.5.0 to 7.1.0, we noticed a large increase in build time for our project. By looking at detailed build times, we could attribute all of it to a single command: cordova prepare.
When I wanted to replace my local TeamCity based deployment setup for my blog with a hosted one, I chose CircleCI based on its good support for private repositories in BitBucket and an abundant free offering. The migration process went surprisingly smooth, even though I had to change the technique I used for deploying to Azure since there's no Web Deploy on Linux.
Posts in March 2018
During development, Ionic replaces the default Angular error handler with its own implementation which displays the error details in a page overlay instead of just printing them out to console. If you want to automatically report these unhandled errors to your analytics service, you can replace that error handler with your own custom one.
Angular comes with built-in Cross Site Scripting (XSS) protection, which prevents you from using unverified dynamic values in certain contexts inside your generated page. Most of the time you shouldn't even notice this. But when you do, it's good to know how you can work around the restrictions set by this protection.
Although comments in HTML markup usually don't play an important role (they are comments after all), they could have a meaning for parsers which post-process the HTML document. When I recently encountered such a requirement, it turned out that generating custom HTML comments with an Angular application is not as easy as one might expect.
Most built-in components in Hippo CMS have a link to one or more documents as they are designed to render the CMS content documents. Sooner or later you'll want to achieve that with your own custom component as well.
As a part of getting acquainted with Hippo CMS I took on the task of creating a custom Hippo component for including a Stencil web component in a portal page using the CMS editor. I based my work on a similar component I found on GitHub for a Polymer web component.
Posts in February 2018
Stencil is a new lightweight framework for creating web components from the authors of Ionic. It's going to form the basis of components in Ionic 4, which will make them framework agnostic and hence allow writing Ionic applications in frameworks other than Angular. Although Stencil is still in early stages, I decided to give it a try and see what the experience is like.
Flexbox greatly simplifies many HTML layout scenarios. Although it is already broadly supported in browsers, sometimes incomplete implementations can still make your life difficult. For example, in version 10 of iOS Safari, height of flexbox children isn't treated as explicitly set when defined by the parent flex container.
Slides is a highly configurable Ionic component, even without accessing the underlying Swiper API directly. In this post I will make it show a small part of the neighboring slide on both sides.
Posts in January 2018
There are two functions for dismissing a loading indicator instance in Ionic: dismiss and dismissAll. The former will only close the specific instance, while the latter will close all currently opened instances. However, it's better to avoid dismissAll unless you really need it, because it could leave an instance open which would be closed correctly if dismiss was used instead.
Logging to browser console can be a useful tool for troubleshooting Ionic applications during development. Although all the logging is still done in test builds, the process of getting the log from the device is not tester-friendly. Without too much effort this experience can be improved a lot by adding an option to export the log directly from the application.
RxJS used to encourage monkey patching of operators and helper functions onto the Observable object. However, this has an unfortunate side effect of making the imports available everywhere. Removing an import from one file can inadvertently break code in other files. To alleviate this problem, alternative imports in the form of lettable operators are available since RxJS 5.5.
Ionic 3.5 introduced the concept of multiple root navigation elements to fully support SplitPane, for example. This required API changes, among others making App.getRootNav() function deprecated. However, there's still no good answer to what the value of the required parameter for the replacement function should be.
Posts in December 2017
It's December again and for the third year in a row I've spent a significant amount of time solving Advent of Code programming challenges. To make it even more interesting, I decided to write the solutions in Kotlin - a programming language I heard a lot of good things about, but had no prior experience in.
Ionic serve can be a very useful tool for tweaking the design of pages in Ionic applications. However, if your application is using native plugins, some of them might fail with Ionic serve.
Cordova config.xml file contains some information that might be different between the test and the production builds of your application, e.g. preference values or even the application id. This could be solved by having a separate branch in source control with these changes, but you could also modify the values just before you start the build on the build server.
At the end of November the second part of my Visual Studio video course was published. With that, all of the materials which I was recording during summer and early autumn are finally available for everyone to watch.
For several years now Garmin Oregon 600 has been my trusty companion when I go hiking or geocaching. To take full advantage of it, you also need good topographic maps for your region. You can buy them from Garmin, but they are not always very accurate and up-to-date. Since I learned about the free OpenStreetMap based alternative Freizeitkarte, I never looked back.
Posts in November 2017
Ionic framework (as well as Cordova, which it is based on) do a great job at abstracting away the details about the platform that the application is currently running on. There are ways to get that information from Cordova, but it's important to understand what exactly the values returned mean.
Cordova has well documented support for modifying the contents of AndroidManifest.xml file from a plugin by adding config-file and edit-config elements to its plugin.xml file. It's less obvious that these same configuration elements can also be used directly inside the application's config.xml.
In native Android applications, the version of build tools and SDK to build them with can be specified directly in the Gradle build script. In Cordova applications, the build file is automatically generated, therefore any manual changes to it will be overwritten. The question is, where do the values in the generated file come from.
I've been pretty busy since early summer, spending most of my spare time recording a video course about features for debugging and testing in Visual Studio 2017. Since Monday, the first part of this video course is finally available to everyone.
Posts in October 2017
Promises make it easy to handle errors in asynchronous method calls. The rejection handler can be used to log full error details from a rejected promise. It will also catch any errors that might happen in the fulfillment handler. However, the Error object details might not get logged as you would expect.
To reference DOM elements in the component template from the component code, ViewChild and ViewChildren decorators can be used. Similarly, ContentChild and ContentChildren decorators will provide access to DOM elements in the component content. Still, I had a hard time coming up with a way to support a scenario where the component consumer should be able to tag some of the DOM elements that need to be processed by the component.
Angular directives are a great way to extend behavior of Angular components and HTML elements. As long as you only need a reference to the host HTML element to implement your functionality, Angular dependency injection will easily inject it as an ElementRef, along with a Renderer to modify it. If you also require a reference to the host component, it gets a little more complicated.
Slides is a very flexible Ionic component for presenting multiple slides to the user who can swipe between them. However, not all its customization options are exposed as Angular Inputs and Outputs or even fully documented. To see all supported options, one can peek into the source code. The only way to learn more about them is to check the Swiper API reference, which the Slides component is based on.
Posts in September 2017
Ionic applications have built-in support for Android's hardware back button. For the root page it closes the application by default. There are ways to change that behavior, though.
Although the official Ionic templates aren't preconfigured for unit testing, there is no lack of guidance in this field. It's not all that difficult to get started with unit testing any more. However, as the number of tests in the project will start to increase, it will soon become obvious that the test are quite slow.
Ionic Native makes it very convenient to use Cordova plugins from Ionic applications. Although Ionic Native provides an impressive collection of wrappers for many Cordova plugins, there are still Cordova plugins out there without a corresponding plugin. In such cases you will need to either use them directly without a wrapper or write your own wrapper. The latter option is much simpler than you might think.
When trying to capture camera video from browser using MediaDevices.getUserMedia, user consent is required. On first call the browser will show a dialog to the user who can either allow or block access to the camera. It might be useful to have some analytical data for your application on how many users blocked the camera access, but unfortunately there's no direct way to detect from code when the dialog was shown and how the user answered.
Posts in August 2017
If you want to use Google Analytics as the analytics tool for your Ionic mobile application or progressive web application (PWA), there's an Ionic Native wrapper available for the Cordova plugin with support for mobile platforms as well as the browser (web) platform. Unfortunately, it consistently threw errors for me, when I tried to send a screenview event for the entry page.
By default, all text in Ionic 2 uses Roboto font, which is also bundled with the framework and automatically distributed with every created application. This all sounded great, until I noticed that some characters are rendered with a different font.
Ionic has no built-in support for Firebase Cloud Messaging (FCM), which is now also Google's official push notification infrastructure for Android. However, since Ionic is based on Cordova, it's still easy to make it work with one of the available Cordova plugins.
Posts in July 2017
I was convinced that it doesn't matter in what order plugins are added to a Cordova project. However, I recently encountered an issue with unexpected entries in iOS Info.plist file, which turned out to be caused by incorrect order of plugins in config.xml file.
I have finally updated Android SDK to the latest version, because I wanted Android Studio to stop informing me about available updates on every startup. Unfortunately several breaking changes have been introduced since the version I was using before, which altogether broke my regular flow of work.
Proguard is an optimizer and obfuscator for Java code. It can easily be enabled with only a few entries in the Gradle build script. In Cordova applications, the build script is regenerated on each build, therefore you'll need a plugin to add the required entries to it unless you want modify it by hand every time.
Posts in June 2017
The last Slovenian Developers User Group meeting before the summer break consisted of the two most popular sessions from Microsoft NT Conference, as voted by the user group members.
I've been doing a lot of Ionic 2 development lately in Visual Studio Code lately. The editor has great out-of-the-box support for TypeScript, HTML and CSS editing. There's also a lively ecosystem for extensions, which can improve the development experience even further. I'm going to describe my current configuration and the selection of extensions that I'm using.
The biggest advantage of having a formal description for a RESTful API is the ability to programmatically generate client-side code for calling the service. Unfortunately, it turned out that Swagger tooling still leaves much to be desired, at least for generating TypeScript Angular code.
Recently, I was troubleshooting a curious bug that only happened on one page in my Ionic 2 application: new values from an HTTP request only showed on the page after a click instead of immediately. Wrapping the update code in NgZone.run() helped. However, it bothered me why this was only necessary in this single instance.
Posts in May 2017
I keep getting impressed by how feature-rich dependency injection in Angular is. This time I needed it to inject the appropriate implementation of a dependency based on runtime information. Of course, the scenario is well supported.
At the beginning of this week the traditional NT Conference was taking place in Portorož. I had my only session this year on Monday, where I talked about .NET Core and .NET Standard.
Angular has an impressive dependency injection system, however some aspects could be documented better. Old blog posts explaining how things worked before the final release don't help either. Hence, it took me a while to successfully intercept HTTP requests and inject a common parameter.
When using tabs in Ionic 2, each one of them contains a page that doesn't know anything about the other pages nor their common parent page hosting the tabs. This makes it challenging to switch tabs or pass data between them.
Posts in April 2017
On Saturday the fifth annual Global Azure Bootcamp event was taking place all around the globe. In Slovenia the event was organized in Ljubljana at the premises of the local Microsoft subsidiary. I showcased the Visual Studio integrations for Azure Storage, Application Insights and publishing of ASP.NET Core web applications to App Service on Windows and Linux.
Angular has great support for validating data in forms, both template-driven and and reactive ones, built imperatively with FormGroup. It is also easy to create own custom validators. However, I did not find it obvious, how to use injected dependencies in non-directive validators for reactive forms.
As a part of setting up the Ionic 2 project I am currently working on, I decided to also configure end-to-end testing using Protractor. I based it on the excellent Clicker demo project. It worked great for running tests during development, but lacks support for headless test execution on a build server.
Ionic 2 includes many components and native wrappers out of the box. However, you will probably want to share some of your own code between projects if you are working on more than one of them and they are at least remotely similar. Since Ionic 2 builds on top of Angular, shared modules are the right tool for the job.
Posts in March 2017
Although there's a lot of talk about Ionic 2 being suitable for creating progressive web applications (PWA), there's little guidance on how to actually configure a project to achieve this. In this post I am listing everything I changed in my project, to build a mobile web application (not yet progressive).
Many Angular 2 and Ionic 2 APIs return RxJS observables. To unit test your code that's consuming them, you will need to create your own observable streams with test data. With this approach I wrote tests for code reacting to user's current geolocation.
In modern HTML 5 browsers you can render video from your camera inside a web page using the video element. However, to further process the captured video or add some custom rendering on top of it, the canvas element needs to be used. Due to the ever changing APIs in this field, it's not easy to find up-to-date working sample code for achieving this.
Tuesday was the Visual Studio 2017 release day. To celebrate this occasion, Microsoft organized an official 2-day launch event. It was accompanied by a large number of local events all across the world. One of them was organized in Ljubljana as well. I had a short session there, presenting the most important new features and improvements in Visual Studio 2017.
Braintree's Hosted Fields offering is a great compromise between payment form customization and PCI SAQ A compliance requirements. Although it is not immediately evident from the documentation, the payment form can also easily be extended with custom data fields that your business might require. This post demonstrates how to do it in an ASP.NET Core application.
Posts in February 2017
Angular makes heavy use of ECMAScript 2015 modules. All components and other Angular objects are modules themselves, therefore the tutorials explain early on, how to import and use them. However, how does one import a third party library which still exports legacy CommonJS or AMD modules?
By default, Ionic 2 produces unminified development builds. To force an optimized production build, you need to add --prod switch to ionic build or ionic run command. Since development build doesn't include Angular AoT (Ahead of Time) compilation, your production build might turn out broken even if development build of the application worked just fine.
In Windows, there are two approaches to accessing Git repositories using SSH. Command line Git distribution and posh-git are preconfigured for OpenSSH, while SourceTree by default relies on PuTTY. The two stacks use different formats for storing both private and public keys. Fortunately, there is a way to convert between the formats using PuTTY's key generation utility.
Windows 10 by default doesn't come with .NET Framework 3.5 installed, however some older applications still require it. You can install it by enabling the corresponding Windows feature, however you need to be online for this to work. Fortunately you can use DISM.exe to work around that requirement.
Posts in January 2017
In version 2.1 that was released in December 2016, TypeScript finally added support for downlevel transpilation of async and await keywords for ES3 and ES5 targets. To give this new feature a try, I decided to convert the Angular Tour of Heroes tutorial to use async and await.
When exposing your TeamCity build server to the internet, you'll want to use HTTPS so that users won't have to send their passwords over an unencrypted connection. Thanks to Let's Encrypt, you can now get the SSL certificate for free, but there is still some work involved to get everything configured correctly.
The official Android emulator has a big disadvantage for regular users of Hyper-V: you cannot run the emulator accelerated when Hyper-V is enabled. Fortunately, there is an alternative: Visual Studio Emulator for Android, which uses Hyper-V for hardware acceleration.
Many operators and other symbols in programming languages consist of multiple characters, but still represent a single token. Although as programmers we learned to view these symbols as single logical units, ligatures allow joining of multiple neighboring letters into a single glyph. With correct fonts and editor support these can be used to improve the rendering of source code on screen.
Posts in December 2016
For the second year in a row, I spent a significant amount of time in December solving the Advent of Code programming puzzles. Before writing the first line of code, I created a repository for my solutions. Unlike last year, I wanted to have all the code readily available for future reference. More than once, I actually looked up previous solutions while solving a more recent puzzle.
Posts in November 2016
Ionic 2 is the successor to the quite popular hybrid mobile framework. It is based upon Angular 2, but unlike it, it hasn't yet reached the final release; the latest version is Release Candidate 3. This makes it still a bit rough around the edges and lacking in documentation. Debugging with source maps is one of the features, which still pose a challenge to set up for many developers.
Posts in October 2016
Having unit tests usually drastically reduces the need for interactive debugging. However, being able to debug unit tests can sometimes prove very useful. Nowadays, any browser includes a fully featured debugger as part of its developer tools, and Karma test runner has a dedicated feature for in-browser debugging. I wrote short instructions on how exactly to use this feature for a project I am working on.
Although, I have now configured my Cordova project to automatically copy distribution files from installed Bower packages and reference them from HTML pages, there's still one final part of Bower-related configuration left: unit tests also require Bower dependencies. I don't want to manually update the configuration of my test runner every time I install an additional Bower package.
Posts in September 2016
If an Excel file contains links to other workbooks, Excel will offer to update the data every time you open the file. If the linked workbook doesn't exist, it will provide an option to edit the invalid link. There is an option to remove it in the dialog that opens. Unfortunately, the command silently fails in certain scenarios.
This week the second community organized Cancel conference was taking place in Ljubljana. It spanned over two days. Thursday was the main conference day with 20 sessions grouped in 4 tracks. On Wednesday afternoon preconf was organized at the premises of Microsoft Slovenia. I had my sessions on both days.
Posts in June 2016
The introduction of diagnostic analyzers in Visual Studio 2015 significantly lowered the bar for development of custom static code analyzers. The supporting infrastructure makes it easy to have the same static analysis run after every commit as part of continuous integration on your build server - you just need to configure your Visual Studio projects correctly.
Posts in May 2016
It's May again, which means the annual NT Conference was taking place in Portorož at the beginning of this week. This year I had two sessions scheduled, the first one on Monday and the second one on Tuesday.
Posts in April 2016
When Lifeline was originally released in 2015 for iOS, it became the number one paid app in the App Store. Although, in essence it was just a text based adventure, it took full advantage of interactive notifications introduced in iOS 8, creating an illusion of real-time communication with the stranded astronaut Taylor. While Windows Phone 8 and 8.1 had no support for custom toast interactions, making the experience impossible to recreate, notifications in Windows 10 are on par with iOS and Android.
Posts in March 2016
Post requests in web applications can often confuse less technically savvy users and in the worst case even cause inconsistent data if a non-idempotent post request is repeated. Post/Redirect/Get is the design pattern that's typically used to avoid most of the undesired side effects of post requests. Of course, the pattern can easily be implemented in Grails, as well. Though, when using namespaced controllers, things can get a bit more complicated.
In web applications, server-side code will sometimes need access to additional external resources, such as font files, certificates etc. If you want to distribute them as part of your application, the path to the corresponding files will need to be determined at runtime, as it depends on the deployment location. As far as I could determine, there are two options, where to put such files.
New versions of applications introduce new features. Sooner or later this inevitably causes the format of locally stored application data and settings to evolve, as well. To avoid loss of data or even application crashes, newer application versions must be able to at least read older data formats or convert them to its own native format. The option of having data roamed between different devices with potentially different versions of application, can make handling data format changes even more complex.
Posts in February 2016
Newly created classic virtual machines in Azure have dynamic public IP addresses. Although, Resource Manager is now the recommended deployment model, there are still image templates in the marketplace that requires classic deployment model. If you don't want the IP addresses of these virtual machines to change when they are stopped, you will need to reserve the IP. At the moment this can only be done using Azure PowerShell.
Having leftover Azure credit from my MSDN subscription made Azure a logical choice for hosting Docker in a Linux virtual machine. This post documents the steps I took to create a convenient working environment on my Windows workstation.
At first sight there doesn't seem to be a way for a universal Windows application to be directly notified, when one of its background tasks has completed. Fortunately, there is an event that will get raised when a specific background task completes. In this post I'll explore how to take advantage of it and what it allows you to do.
There are a lot of features in WPF that are not available in other XAML dialects, such as the latest one for Universal Windows applications. One of them is multibinding, which allows binding of multiple view model properties to a single dependency property of a WPF control. Fortunately, there is a third party library available which makes this possible in UWP apps as well.
If you're used to the old ASP.NET, it's not all that obvious how to deploy an ASP.NET Core application to IIS. Although, there is documentation available for the process, I still struggled a bit, before I got everything working. This post contains the steps I had to take, so that I can simply follow them the next time. At least, until something changes again with one of the future releases.
Are you used to the fact that strings are null-terminated? Well, in .NET framework they are not. In this article I explore the consequences of that, explain the circumstances under which you might stumble across it, and suggest, how to avoid being affected by it.
Posts in January 2016
JSData is built around resources and CRUD operations on them. It is an easy to understand abstraction as long as our domain maps well to it. Getting a filtered subset of resource instances is a common enough operation which can introduce subtle bugs if not implemented correctly. Defining nested resources in such cases is a good idea when wanting to avoid too many parameters in query strings.
Posts in December 2015
Ever since I have tried out NCrunch, I never looked back. Continuous running of tests as implemented in NCrunch significantly changed how I look at tests. Since then continuous testing has become much more mainstream and today both ReSharper and stock Visual Studio offer support for it. It was about time I took another look at the other tools and see how they compare to NCrunch today.
Under what circumstances can a static field be initialized multiple times? C# language specification makes it pretty clear that static fields are initialized only once, before the class is first used. This meant, it was time for some creative thinking, when I encountered an issue, seemingly caused by the static field being initialized multiple times.
You might not be aware of it, but Visual Studio projects have additional identity beyond their project file name and path. Each one of them contains a GUID value which should by definition be unique in normal circumstances. The troubles begin, when you create a copy of a project by copying its folder and renaming the files.
Posts in November 2015
When I tried to run a universal application in the Windows Mobile 10 Emulator today, I was greeted with an error. The phone OS in the emulator was unresponsive and Visual Studio couldn't deploy the application to it. Here's the solution that worked for me in the end.
Today the first TechDays conference of 2015/2016 took place at the premises of Microsoft in Slovenia. Me and Andrej Tozon, a fellow Slovenian Microsoft MVP, did a track on Windows 10 Universal Apps. He started with 2 overview sessions about what's new and how to migrate existing Windows Store and Windows Phone applications to the new development platform. I followed with a deep dive into 2 more specific topics.
I recently broke my streak of 3 Windows 10 upgrades without any issues whatsoever, when I needed to upgrade my new Lenovo laptop. I downloaded MediaCreationTool to create a bootable USB stick for a clean Windows 10 installation. After the download got stuck at around 30 %, I killed the MediaCreationTool process. When I tried to start it again, it failed with the following error: Setup couldn't start properly. Please reboot your PC and try running Windows 10 Setup again.
Posts in October 2015
Based on Visual Studio user experience, one would think running unit tests for Windows Store apps is not all that different from running standard .NET framework unit tests using MSTest testing framework. When you try running them on a build server, it turns out there are a lot of differences.
Whenever I'm developing a non-desktop Windows 8 application I prefer having as much business logic in portable class libraries as possible. The test project can then be a standard .NET class library, allowing mocking frameworks and other helper libraries to be used which are not available elsewhere. Having a dependency on a native platform specific library, such as SQLite, can still complicate things a bit.
When I moved my blog to Azure, I broke the AWStats statistics, which I had configured, when I was still hosting the blog myself. Almost a month after the move it was about time to get it working again.
The new version of NDepend brought many new features; among them also integration with TeamCity build server. This convinced me to give it another closer look; evaluating how taking advantage of this can contribute to increasing code quality in larger development teams.
This week the first Cancel conference was taking place in Nova Gorica. I had the last two sessions in one of the development tracks: Diagnostic analyzers in Visual Studio 2015 and Debugging in Visual Studio 2015. Slides and demos are available for download.
Posts in September 2015
Before I finally settled with using Web Deploy for deploying my site to Azure, I was also considering using FTP directly from Grunt. I quickly chose grunt-ftp-push as the most promising package for this purpose. A greater challenge was finding a way to keep my FTP credentials out of my gruntfile and source control.
Redirecting old URLs to their new counterparts is an important part of restructuring an existing web site or migrating it to a new engine. In a previous blog post I've already described, how I kept all permalinks working after the migration. I didn't want to create full rewrite maps for redirecting month and date pages; creating a more generic rule made much more sense in this case.
After the last reboot my TeamCity build server suddenly stopped working: 404 errors were returned instead of TeamCity dashboard. It turned out some other process was already listening at port 80 when TeamCity was starting up. It must have been something new I installed since the previous reboot.
Although Git-based continuous deployment of my site to Azure seemed like a good idea, it turned out too unreliable. I didn't manage to get to the bottom of the issue. Instead I started exploring the alternatives. I decided to use Web Deploy, because it is reasonably easy to set up and it also supports deleting of removed files from the deployment location.
I was expecting in-depth content, describing the good and bad practices in different scenarios supported by measurements, pitfalls to be aware of, options to consider. Instead I only got a high-level overview of several performance related aspects, at best.
Posts in August 2015
One of the main DocPad features is support for layouts, which are used to ensure a common design for multiple pages. Layouts can even be nested, which opens doors to a new set options. A typical scenario for using them would be several different types of pages in a single site with a common basic design.
After successfully migrating the content from the old DasBlog site to the new DocPad based one, it was time to generate permanent redirects of old URLs to new ones. Since the site is going to be hosted in Azure, I decided to use the URL Rewrite module - rewrite maps to be exact; because I need to map a large number of individual URLs, which can't be covered by a generic rule.
I recently deployed my new web site to an Azure web app for the first time. The site seemed to load correctly, but a closer inspection with Fiddler revealed a couple of 404 errors. Font Awesome web font files appeared to be missing, although they were present on the web server, but by default files with .woff2 and .woff extensions are not served.
In the scope of changing my blogging platform I also decided to switch from self-hosting the blog to hosting it in a Microsoft Azure web app. One of the available features, I want to take advantage of, is continuous deployment from a Git repository at one of the supported repository sites. Of course, the repository only contains the sources for the site, therefore it will need to be built every time the latest version is retrieved from the repository.
Posts in July 2015
TeamCity has built-in support for gated commit build pattern in the form of pre-tested commits. Unfortunately, to make them work, you need to use a supported IDE or a command line tool. That's why I decided in favor of an alternative approach: automatic merge feature.
One of the most daunting parts of replacing my current blogging platform DasBlog by a site created with DocPad, is the migration of existing content. Being a software developer, I wanted to automate as much of the process as possible. Even if the total time required wouldn't be all that much shorter, I'd rather spend it writing scripts and learning new tools and technologies, than doing mundane tasks.
Posts in June 2015
If you're looking for a book to learn SignalR from, you can't go wrong with this one. On the other hand, if you're already fluent in SignalR and just want to learn more, it probably isn't your best choice, unless you're interested in one of the above mentioned topics.
I have no reservations about recommending the book to any existing or future TypeScript developer. It can serve as the first book to start learning the language, but can teach you a lot even if you have already been programming in it for a while.
Packt Publishing has started a new initiative; offering a different ebook for free every day. You have a 24 hour window during which the daily book is available, before it is replaced with the next one. You should check the page every day and download any books that might interest you.
Posts in May 2015
Recently I was involved in troubleshooting a strange performance issue, manifesting itself in the form of long initialization time of each newly created process or AppDomain on one of the servers. In the end it turned out, it was caused by assembly binding log being enabled on that machine for a long time.
Visual Studio Tools for Unity enable the convenience of developing Unity scripts inside Visual Studio. A naive attempt to install a random NuGet package into the UnityVS project will still most likely fail. To make it work, the NuGet package will need to comply with special requirements. Even then, there will still be some manual work left.
This year I had 2 sessions of my own at NT conference: What's New in C# 6 and Diagnostic analyzers in Visual Studio 2015. Slides and demos for both them are available for download.
Productivity Power Tools for Visual Studio 2013 introduced a great feature called Presenter Mode, temporarily increasing the fonts both in the text editor and Visual Studio itself, without having to change the settings and thus affecting your working environment. Since the extension is not (yet) available for Visual Studio 2015, we need to make do with one of the alternatives.
When an application starts misbehaving in production, attaching a debugger to alive process is out of the question. Creating a memory dump and analyzing it in WinDbg is the way to go. Most of us are required to do this on rare occasions only. To make it easier for me in the time of crisis, I created a short cheat sheet.
Effective development of diagnostic analyzers strongly depends on unit testing. Debugging diagnostic analyzers requires a second instance of Visual Studio to be started which will host the debugged analyzer as an extension. This takes far too long for being useful during development, therefore using tests instead is a must.
Posts in April 2015
Diagnostic analyzers are a new extension point in Visual Studio 2015, performing source code analysis both at compile time and inside Visual Studio during development. I've created a complete list of software, which is required for you to start developing your own diagnostic analyzers.
The content is not focused only on sagas at all. The samples are very contrived and almost impossible to make sense of by just reading the book. Not even the basic functionality and structure of sagas is properly explained, much less any advanced concepts and usage scenarios. I can't really recommend the title to anyone.
Posts in March 2015
The book falls a bit short and remains just an overview of methodologies and approaches, with lots of pointers to further resources. It is still a good starting point to learn about DevOps: what it is and why you might want to take on the task of implementing it.
Whether you're starting to learn about NServiceBus, considering the adoption of distributed architecture in a .NET framework based project, or just want to know what NServiceBus is about, you should read this book.
Writing a build script was only the first step in setting up continuous integration. In this follow-up post I describe how to configure TeamCity for Grunt and provide a couple of hints how to make it work even better.
Since my first DocPad project is slowly nearing completion, it was time to create a build script for it. I decided to use Grunt, which allowed me to achieve everything I wanted to: generate the static site, detect broken links in it, and deploy it to the web server.
Posts in February 2015
ResourceDictionary is not a generic type, hence the above error makes no sense. Still, you can encounter it in a WPF project if certain conditions are met. The post describes these conditions and suggests the workarounds I know of to get rid of this bogus error message.
On most platforms MvvmLight includes a helper class to invoke commands from events. In WinRT it is suspiciously missing. Fortunately, since Windows (Phone) 8.1 you can find a replacement for it in the Behaviors SDK extension.
The book is actually a step by step guide to iOS development in Swift for complete beginners. By the end of it the readers should have enough knowledge to write their first simple iOS application even without any previous experience.
Posts in January 2015
On Tuesday Microsoft Slovenia organized the second TechDays event leading up to the 20th NT conference. The event consisted of 4 tracks; I had the opening session for the Visual Studio 2015 track. As always slides and demos from my session are available for download.
For some reason display drivers for both NVIDIA and AMD graphics cards have a tendency to scale image to full panel size instead of keeping the default aspect ratio. If you don't like to see your image stretched, you can change the behavior in the corresponding control panel. After recent driver updates both control panel applications got broken somehow on two desktop machines I'm taking care of.
Windows Store apps store their settings in a registry hive file named settings.dat. Even after loading it into registry the values inside it are non-standard which makes them difficult to read and edit. The post dives into their serialization format and guides the reader through developing a PowerShell function for editing the values.
AWStats is one of the most popular tools for generating web site statistics from server logs. I've recently set it up on my Windows web server to generate statistics for my blog. This post contains the required steps to make it work.
Posts in December 2014
I can recommend the book to anyone having TeamCity as their continuous integration server, as well as to those who are considering it as their first or new solution for continuous integration.
AutoMapper is a popular object mapping library for .NET framework. By default its configuration is defined statically, but there is a way to do it non-statically and use per-instance dependencies inside the mapping code.
Canon's LiDE series of scanners has no official support for years and there are no official drivers for recent versions of Windows. Nevertheless, it's still possible to make them work perfectly and avoid buying a replacement for a still functioning device.
Microsoft Access is an often overlooked part of Microsoft Office, but this doesn't stop it from still playing a mission critical role in some companies. In such cases AccessFIX can be a life saver when important data gets deleted or the database gets corrupted and there's no backup available.
The general advice is to avoid using IoC containers in your test code altogether. Unfortunately achieving that when IoC usage is being retrofitted into an existing application, can be challenging. Failing to do that will quickly result in having to reconfigure your IoC container for some of the tests.
Posts in November 2014
Encouraged by Scott Hanselman's Get Involved video, I started experimenting with DocPad. Recently I wanted to perform a simple task of grouping a list of pages by the month, they were published in. In .NET I would use LINQ and be done with it in a matter of minutes. Doing this in my new technology stack took a bit more time.
The more I use FluentAssertions, the more I like its flexibility and extensibility. In this post I'm going to focus on assertion rules which can be used to define custom equality comparisons for specific types.
One of the main reasons for using an IoC container like Ninject is to be able to inject different dependencies into your classes in production code and in test code. Usually you don't even need to use an IoC container in your tests, but when you longer lived dependencies will usually be scoped differently in test code than they are in production code.
Unit tests best serve their purpose when they are brief and easy to understand. There are cases when it can be difficult to achieve this; nevertheless it's still worth putting in the effort, as it may pay off.
Posts in October 2014
In the field of software architecture the terms publish-subscribe pattern, event aggregator, and message bus are closely related to each other. My coworker and friend Goran Šiška recently published the first version of LightMessageBus, his own minimalistic event aggregator. I decided to spread some word about it by giving it a proper introduction.
If you know your way around Unity, the book will probably teach you a couple of very specific advanced techniques; just don't expect to gain much general knowledge about 2D and 3D graphics, AI and shaders, or you'll be disappointed.
Git's default installation only makes it available from com command line in its embedded terminal. As a regular user of ConEmu and PowerShell, I wanted to make it work in my system command prompt with tab completion and credential caching.
Windows Workflow Foundation built-in persistence support can be extended by its host to save additional data. There are a couple gotchas to be aware fo when trying to ensure transactional consistency between the built-in and host-specific data.
Posts in September 2014
When working with complex data structures in your unit tests, you often end up with a lot of plumbing code. FluentAssertions is a library for .NET framework which can simplify your assertion code and at the same time make the error messages much clearer when tests fail.
I focused on the advantages NuGet brings to the process of managing project references, but also gave a short tutorial on how to create and publish a new NuGet package. I concluded the session by taking a broader look at the NuGet ecosystem and the tools improving it and taking advantage of it.
It's always best to completely avoid using reflection, but unfortunately that's not always possible. Sometimes you need to use APIs, which are not strongly typed. In such cases you should transition from reflection to strongly typed code as soon as possible: because of performance, and because of code readability as well. In this blog post I'll describe a couple of techniques which are useful in situations like this.
SlowCheetah is a very useful Visual Studio extension which builds upon Visual Studio's built-in support for Web.config transformations. It adds similar XDT transformation file support to non-web projects which can be used even during debugging, while built-in solution for web projects only works for web deployment. There is already a feature request for SlowCheetah for it, but until it's implemented, you'll need to find a different solution.
According to the C# language specification, the static field initializer should execute before it is accessed for the first time. As it seems, looking up the field value in debugger doesn't trigger the initializer.
Posts in August 2014
After I set up multiple different configurations for my ASP.NET project with different .config file transformations for different environments, a build error started showing up every time I changed to a different configuration. The issue could be resolved by manually deleting a file from obj folder, but I soon got tired of this and decided to investigate further.
Static code analysis is a very useful feature of ReSharper. The generated warnings can help you fix bugs which might otherwise remain unnoticed. Unfortunately static analysis is not perfect and it might detect false positives. There are a couple of ways to tell it not to warn us about specific ones any more.
No matter how well versed you with C#, the book will teach you something new about it or at least remind you about the stuff you already know without being consciously aware of it. Since the author lets you choose the price for the book, you'll certainly get your money's worth from it.
One of the more attractive parts of Windows Workflow Foundation is its workflow designer and the possibility of rehosting it in your own application with a minimum amount of code. Often simple rehosting of the designer is enough, but sometimes you will want to do some additional background processing of the workflow as the user is designing it. In this article I'm going to present a way for achieving that.
Portable class libraries have recently become so ubiquitous, that it's easy to forget they don't exist all that long. As long as you're using Visual Studio 2012 or later and targeting .NET 4.5, this is not really important. But once you start targeting .NET 4, you should better keep that in mind.
Creating a Windows service in .NET could hardly be any easier. Installing multiple instances of such a service on a single computer is not that easy. Since there's not much documentation about it, many articles are describing over-complicated custom solutions instead of taking advantage of the APIs that are already available.
Posts in July 2014
I can sincerely recommend the book to anyone, trying to get a glimpse into the world of game development. It can really only serve as the first step on the path to becoming a game developer, but it's definitely enough to see if that's something for you and worth exploring further.
Navigation in Windows Store apps is strongly based on the browser model, i.e. the application is keeping a back stack of previously shown pages which will be traversed again when navigating back. but there are some cases in which you don't want the user to navigate back to a specific page in the history. There's no such built-in functionality available in MvvmCross, but it's really simple to add it with the right approach.
I'm developing an application in MvvmCross, using SQLite for local data storage. I'm taking advantage of MvvmCross SQLite-Net plugin. Recently I stumbled across a very strange behavior, involving a fairly simple table with a DATETIME column. It turns out, SQLite's handling of DateTime values is quite strange.
IDataErrorInfo interface is really handy when implementing data validation in WPF. There are many different ways to implement IDataErrorInfo for a DataContext. But since I've recently become quite fond of FluentValidation library for implementing validators, I'm going to focus on using it in this post.
Packt Publishing is currently celebrating 10 years of its existence. For this very special occasion they have decided to offer a significant discount on their complete catalog of eBooks and videos - until July 5th all their titles can be purchased for just $10. Since I'm also the author of NuGet 2 Essentials, one of the books in their line-up, I encourage you to take a closer look at this book.
Posts in June 2014
XAML has first class syntax support for binding to indexed properties, such as Dictionary. Real properties still have their advantages over indexed ones, such as full support for implementing INotifyPropertyChanged. For Dictionary properties this can only be done for all items in the collection at once. Unfortunately, in Windows Store applications this causes problems when there are bindings to keys that are not present in the new Dictionary.
The best resource on the subject of testing navigation in MvvmCross view models that I managed to find, was Slodge's blog post from almost two years ago. While it still contains useful guidance for today, there have been changes in the framework. After I got it to work in my own project I decided to publish a more up-to-date set of instructions here.
Posts in May 2014
Having a parameter of type List is not recommended; IList or even IEnumerable should be used instead when a parameter is only going to be used for iterating through the list of items. This way different types of collections, such as arrays, lists, etc. can be passed to it. But IEnumerable can prove even more useful in certain scenarios.
FluentValidation is a small portable validation library with fluent interface. The fluent API makes validators easy to write and understand. You can find a lot of information about basic usage and even more advanced scenarios in very detailed documentation. I'll rather focus on extending the library with your own custom validation.
Most of the time there's no need to use an IoC container in unit tests. Still, testing the IoC container configuration makes sense in an application to avoid runtime errors which will occur when not all required dependencies for the created object are registered in the application beforehand. This doesn't necessarily mean, the right implementations are being used for all dependencies, but that's not what we want to test.
What could have been a show case of designing great UI featuring Telerik's controls with recommended best practices and usage patterns, turned out to only be a shallow overview of a small subset of available controls, interspersed with random opinionated half accurate information.
A couple of days ago I encountered a surprising FileLoadException. The key to the solution was in carefully reading the complete exception message. The last sentence made it clear that strong name validation had failed.
Posts in April 2014
The book is a great first step into the world of Xamarin.Android for a seasoned .NET C# developer with no previous development experience on Android. It's definitely enough to get you started and makes it much easier to decide whether this is the right way to build Android applications or not.
In sqlite-net only the first statement in a command is actually executed. The remainder is silently ignored. In most cases you won't notice that when using sqlite-net. You will either use its micro ORM layer or execute individual statements. The only common exception that comes to mind, is trying to execute DDL or migration scripts which are typically multi statement batches.
On Wednesday I had my only session at the spring NT conference in Bled this year. I was speaking about the new stuff for developers in Windows 8.1 Update. After a short mention of the universal project, I focused on the changes available only to sideloaded enterprise applications.
Posts in March 2014
Recently a colleague of mine mentioned that he has just learned about KeyedByTypeCollection, although it has been included with .NET framework since .NET 3.0. I'm writing this post, because I didn't know about it until that day, either. This leads me to believe that there must be many more developers out there who aren't aware of this niche class being readily available.
A great side effect of view models being implemented in portable class libraries when using MvvmCross, is the ability to unit test them on any platform, not necessarily the one you are targeting. So even when developing a mobile application, you can test it in full .NET framework and take advantage of all the tooling available there.
Certain aspects of Workflow Foundation are still poorly documented; the persistence framework being one of them.
The compiler does not remove static methods when calling through an instance because it does not necessarily know that you are calling through an instance. Because there are situations where it is ambiguous whether you're calling through an instance or a type, it defers deciding which you meant until the best method has been selected.
Last Tuesday the local Microsoft DPE team organized a free event for developers thinking about taking part in the regional Windows 8.1 Developers Contest. It was planned as an effective course for developers not having previous experience with development of Windows Store apps. I presented two sessions at the event.
Posts in February 2014
Although MvvmCross allows creating portable converters which can be used on multiple different platforms, they can still only return types which are also portable. Of course there are cases when it is desirable for a converter to return non-portable classes such as Visibility, Brush or BitmapImage on Windows platforms. The basics are probably already covered by MvvmCross itself; it includes visibility and color converters which can be used on all platforms. Still, there will always be other native classes you will need.
MvvmCross is a MVVM framework for XAML platforms, similar to Caliburn Micro and MvvmLight. Unlike its competition it very much focuses on portability and code reuse across all supported XAML platforms (WPF, Windows Phone and Windows Store), and the Xamarin platforms as well (Xamarin.iOS, Xamarin.Android and Xamarin.Mac). Therefore it has its own approach to creating converters, allowing them to be implemented in a portable class library and reused on all supported platforms.
While refactoring an application hosting workflow foundation runtime, I stumbled upon an inconsistent behavior in handling and validation of workflow extensions added to the host WorkflowApplication.
Since Visual Studio 2012 Update 2 there is a project template available for unit testing Windows Phone apps: Windows Phone Unit Test App. Unlike its predecessor Windows Phone Toolkit Test Framework, it doesn't require the tests to be manually started from the device or the emulator. They can be started directly from the unit test runner's window in Visual Studio. This feature should be a good enough reason for migrating any existing test projects from the old framework to the new template.
Posts in January 2014
If you're used to depend on unit testing during your development or even practice test driven development, working on Windows Phone applications can be a challenge. The fact that the code must always run on the phone (or an emulator), poses some limitations on the execution of the tests.
There's usually no need to unit test the logging code. If you just want to ignore it in your tests, there's nothing you need to do when using log4net. If you want to make sure you're going to log the right information, you can use MemoryAppender in your unit tests.
If you're developing a Windows Phone 8 application which doesn't only connect to public web services to get its data, but also communicates with you own custom web service, you'll want to be able to connect to it from the Windows Phone Emulator with as little hassle as possible. Usually that means that you'll want it to connect to your local IIS Express server.
Units tests are all about testing a specific unit of code without any external dependencies. This makes the tests faster and less fragile, since there are no out-of-process calls and all dependencies are under the test's control. Of course, it's not always easy to remove all external dependencies. One such example is a WCF service using entity framework for database access in its operations.
Posts in December 2013
HTTP protocol defines status codes as the means of informing the client about different error conditions on the server, but it can be beneficial to include additional information about the error. The best approach to it depends on the scenario.
When using NuGet, you typically don't need to worry about its repository location. In simple every day scenarios it just works without even paying attention to it. Once you have more than a single solution file for your product, this default approach starts to break down. To be more precise; the problems occur when a single project file is included in multiple solutions files, which are not placed in the same folder.
Configuring web applications which need to accept client certificates is one of those tasks which I am doing just rarely enough to forget about the issues I had to resolve to make everything work the previous time.
Writing unit tests for code that needs to be run on the UI thread can be quite a challenge in WinRT. TestMethodAttribute supports asynchronous test methods but doesn't run them on UI thread. UITestMethodAttribute runs test methods on UI thread but doesn't support asynchronous methods. Still, I managed to make the test method asynchronous and run it on the UI thread.
NuGet 2 Essentials is an up-to-date complete guide to NuGet, written in a very concise and practical manner with many hands-on examples to learn from and to see the features in action. As the book author, I'm of course biased, but I think currently it is the best available resource for learning about NuGet.
Posts in November 2013
Recently I got my hands on the full version of NDepend and I decided to take advantage of that by trying it out on a couple of projects I am working on, both personally and professionally. It turned out that NDepend isn't all that easy to use if you want to make the most out of it. In this post I'll go over the steps I made to set everything up and reconfigure it in a way that made the results more meaningful to me.
I've been quite happy with NAnt as the tool for writing build scripts. Though, once these scripts reach a certain size, they become harder and harder to maintain. The main reason for that is a lack of modularity.
Since I usually write my unit tests in NUnit, I got into the habit of using parameterized tests when testing methods for which I need to check the result for many different input values. Unfortunately using NUnit is not an option with Windows Store apps. Only MSTest is supported, providing data-driven unit tests for such cases.
I have learned quite a few new tricks while reading the book and I would have even more if it wasn't for my previous hands-on experience with many of the topics covered. If you are considering or already developing parallel or asynchronous code, I strongly recommend reading this book.
Posts in October 2013
Recently the abstract override language construct has been brought to my attention. Knowing about both keywords, there isn't much doubt what it means to the compiler. The combination of both keywords can only be used in two cases.
On Thursday the first day of NT conference 2014 took place in Ljubljana. I had 2 sessions on the client application development track. I opened up the track talking about what's new for Windows Store application development in Windows 8.1. In my next session I focused on development of occasionally connected applications for Windows Store.
Since Word introduced Office Open XML (docx) file format, it became much easier to programmatically generate documents from applications without requiring Word to be installed on the machine for Word Automation to work. Unfortunately Open XML SDK doesn't work with Windows Store applications. The only alternative available for Windows Store apps at the moment seems to be DocIO from Syncfusion.
Posts in September 2013
Windows 8.1 doesn't seem to always ask for location (public or private) when connecting to a new network for the first time, instead it often defaults to public. While this certainly is more secure than the opposite option, it can cause difficulties when trying to take advantage of features that are by default disabled on private networks, such as network discovery and remote access. Since enabling them for public networks would be insecure, the only option to use them on such a network is to change the location to private as it should be.
After switching to TeamCity one of the first tasks was setting up proper backup of its configuration. There are multiple ways to backup TeamCity data. The only one that can be performed remotely is exposed over TeamCity's web UI. Fortunately it can also be triggered via REST API for easier automation.
I've been using Git instead of Subversion for new projects for a while now, though I left many older ones still active in Subversion. During a recent hardware upgrade I decided not to install Subversion server again, but rather migrate the old projects to Git as well. This post describes the process I have come up with, just in case I ever need it again.
Some time ago I published a blog post describing how to handle incremental loading in scrolling lists with large amount of data on Windows Phone 8. After receiving an email asking me for a working solution, I decided to publish it and make it available to everyone, instead of sending it by email.
After a hardware upgrade I decided to switch from CruiseControl.NET to TeamCity for my personal continuous integration server to see for myself how they compare. Since I don't have all that many active projects, the free Professional Server License is a great option to try out all of the features without paying for it. At the same time it should give me enough insight to see whether it has enough advantages over free alternative(s) for the investment to make sense in a larger environment.
Posts in August 2013
The book is a recommended read for any team leader, no matter how much experience he already has in his job. Even if you don't agree with everything, I'm pretty sure the book will act as an eye opener and make you more aware of stuff you already take for granted.
It seems that different String methods handle special 0xFFFD Unicode replacement character in different ways.
It's more than a year since NAnt 0.92 has been released, but if you take a look at the project issues page, many of them still report problems related to finding different versions of SDKs.
the book should be more than enough to get you going even if you've never used StyleCop before. Based on the table of contents I was still hoping for more in-depth information on creating custom rules.
Posts in July 2013
The author really managed to convey a lot of information in a concise and useful way, although not all of the topics are covered equally well: some really do shine, while others could still be improved.
Writing asynchronous code in .NET framework 4.5 is pure joy thanks to task-based asynchronous pattern (TAP) and the async/await syntactic sugar. Although many APIs have been updated since the introduction of TAP to provide task based asynchronous methods which can be used with async and await, occasionally you will still encounter operations in APM (Asynchronous programming model) or EAP (Event-based asynchronous pattern) without a TAP equivalent. Fortunately .NET framework provides helpers which will make wrapping older style asynchronous operations into tasks much easier.
Design is an inherent part of developing Windows Phone applications. Sooner or later you'll need to add some Metro icons to them to represent different actions and items in lists.
I often find myself speaking at technical conferences and user group meetings and due to the nature of my sessions, there are usually demos involved. A particular kind of demos I often struggled with to make them work well within a session, are the ones in multiple steps, i.e. they show the same project or solution in different stages of development.
The book addresses a lot of advanced topics throughout the chapters, as expected based on the target audience of experienced .NET developers. Still, most of the chapters include some basic topics as well, which slow down the pace.
Posts in June 2013
One of the challenges of using MVVM pattern with different UI frameworks that always comes up is how to bind events that are not exposed as commands to the view model. Windows Store apps are no exception to that. In this blog post I'll try to give an overview of the available possibilities one can choose from based on individual requirements and personal preferences.
When you pass an instance of IList<T> to the constructor, the BindingList<T> doesn't create its copy. It serves as a wrapper for it, supporting only the operations also supported by the underlying collection.
In the world of connected applications programmatic HTTP requests are more and more common. In Windows Store applications HttpClient class serves most purposes as long as communication is targeted at services or at least the results are processed programmatically and don't need to be shown directly to the user.
When moving a Windows Phone project referencing Microsoft.Bcl.Async package to a new computer I was unpleasantly surprised. Although I had NuGet package restore enabled on the solution, it not only failed to build, it even failed to load. After some investigation I found out that this was a known limitation in NuGet.
Posts in May 2013
If you've only been using NuGet in typical scenarios with a single solution containing a couple of projects, it probably worked great for you. As soon as the project structure is a bit more complex, things start falling apart. There are two main reasons why it doesn't work as expected when individual projects are included in multiple solution files residing in different folders.
Recently I encountered strange and inconsistent behavior in exceptions being thrown by different file operations in WinRT.
The book does a pretty good job in delivering what it promises, but unfortunately doesn't really get into the advantages of developing an application in F# instead of C#. I see that as a missed opportunity of making the book appealing to a broader audience considering giving F# a more serious look.
Task-based asynchronous pattern has many advantages over other asynchronous patterns introduced in the past, most of them boiling down to the fact that it's really easy to get into and start using it. Like any other technology, it does have its pitfalls and there are many details to know about once you get into more advanced scenarios.
Posts in April 2013
At NT conference 2013 I opened the Windows 8 and Windows Phone 8 Developer Tales from the Tranches PreCon track with a session on Building Connected Apps. I addressed all aspects of network communications, focusing on available APIs but also spending some time on the expectations for mobile applications in respect to network usage.
On the final day of NT Conference 2013 I had my last session. This time I was speaking about my experiences with building LOB (line of business) applications for Windows Store.
At NT conference 2013 I had 3 sessions in 2 different PreCon tracks. Apart from the one on connected apps for Windows 8 and Windows Phone 8 I had 2 consecutive ones, both covering the topic of design patterns, focusing on client application development.
Posts in March 2013
The book seems more like a collection of blog posts, which have passed a much stricter review process. If enough of them are of interest to the reader they should provide enough value to be worth the purchase. Check the table of contents online, before buying it.
In mobile applications there's often a need for scrolling lists with large or even (for all practical purposes) infinite amounts of data which of course needs to be loaded incrementally. This can be achieved in pure MVVM fashion with LongListSelector control.
Posts in February 2013
This book is a really nice introduction to Kinect programming. I can recommend it to anyone who is interested in writing his first Kinect application. It might bore you in certain parts but it will certainly save you time in the end.
Posts in December 2012
In spite of all my previous experience with WPF, I've learned a couple of new tricks while reading it. I'm sure I'll be returning to it from time to time to read up on certain details.
Today our local Microsoft DPE team organized ReBuild, a one day recap of the recent Build conference which was taking place in Redmond a little over a month ago. I had the last session of the day and focused on Windows Store apps: what they were and how to develop them.
Posts in November 2012
This weekend a worldwide hackathon for Windows is taking place in over 100 locations. Among them is Ljubljana where the event started with my 3 hour Windows Store app development workshop.
Posts in October 2012
The 5th Bleeding Edge conference was taking place in Laško. For my session I decided to take a different approach to the development of Windows Store apps: instead of talking about the design or the available APIs in WinRT, I focused on architectural best practices when using C#, XAML and the MVVM pattern.
On Monday our local Microsoft subsidiary organized Visual Studio 2012 bootcamp as a preconference to Bleeding Edge 2012. For my talk I selected 3 new features in .NET Framework 4.5 that excite me most.
If you've tried accessing an OData feed from a Windows Store apps you've already come across WCF Data Services Tools for Windows Store Apps. It's a downloadable package which extends the Add Service Reference functionality in Visual Studio 2012 to support OData feeds. Without it OData feeds can't be added as services references to a Windows Store app project.
Tapping a textbox in a Windows Store app automatically show the virtual keyboard. If this keyboard would cover the tapped control, it scrolls the page just enough to make it completely visible. Most of the time this behavior works like a charm but there are times when the app would work even better if it could be modified.
Posts in September 2012
The course is as close to the experience of studying the topic at a university as possible, hence the name of the company. I can sincerely recommend it to anyone who needs to learn the basics of Entity Framework from scratch.
To celebrate the publishing of their 1000th book Packt Publishing is awarding a free access to their online library PacktLib for 7 days and a free download of one book to everyone who logs in with their existing account or creates a new account between 28th and 30th September.
Yesterday two local development user groups organized a common Visual Studio 2012 Community Launch event. I was one of the four MVPs speaking there. Each one of use prepared a talk on his favorite feature. My topic where Portable Class Libraries.
One of the important aspects of Windows Store application development is the application lifecycle. While at first it might seem a minor detail that can be taken care of late in the application development process, it can affect the application architecture quite profoundly. Therefore it's a good idea to address it soon enough to avoid unplanned refactoring when the application is almost complete.
Today I was setting up my new Windows 8 based development workstation and noticed that the final version of WiX v3.6 has been released yesterday. Without any second thoughts I decided to install it only to find out that setup procedure failed for me with a short non-descriptive message and no additional information immediately available.
Posts in July 2012
Troubleshooting WCF services is often challenging, mostly because of cryptic and uninformative error messages. When you combine that with complex usage and configuration scenarios, it takes time to get to the bottom of the problem. The issue I'm about to describe manifested itself on a production server running a WCF service with HttpModule based Windows authentication. Other authentication methods worked fine, while with Windows authentication WCF returned a rather cryptic error message.
Hooks in Subversion can be used to execute custom logic before or after certain actions in repository: commit, lock, unlock and revision property change. They are defined by specifying a batch script that gets executed at that point. In my particular case I wanted to use a PowerShell script before commit to prevent certain files being committed to the repository.
Lately I am working a lot with SQLite and its .NET client sqlite-net. After discovering a bug and also fixing it in the local files included in the project I am working on I decided to also submit a patch for it. What better reason to finally try out the recently released GitHub for Windows do I need?
The lifecycle of Metro style apps requires them to save their state when they are being suspended by the OS to prevent the potential loss of their state if they are restarted instead of resumed because they were inactive for two long.
Posts in June 2012
The book is a useful resource for anyone working with the latest versions of Entity Framework. Just don't start learning Entity Framework with it; some previous knowledge and experience is definitely recommended to make the most out of it.
Posts in May 2012
My second talk at NT konferenca 2012 was all about helping you get started with developing Metro style application for Windows 8 in C#. I've already put the slides on SlideShare.
On Wednesday I had a talk at NT konferenca 2012 about the changes in Windows Workflow Foundation that we can look forward to in .NET Framework 4.5. The slides from the talk are available on SlideShare.
Posts in April 2012
File IO in .NET for Metro style apps (aka .NET Core) can be a challenge for seasoned .NET developers. The classes in Windows.Storage namespace are different from both System.IO.IsolatedStorage and System.IO and require some getting used to. On top of that even the remaining classes in System.IO are missing some of properties and methods. One such method is Stream.Close().
Since Metro applications are running in a sandboxed environment they only have limited file handling capabilities. The private storage area for each application is conceptually very similar to isolated storage, only with its own API. This still doesn't solve the problem of opening a file in a standard format (PDF for instance) with the associated application.
Posts in March 2012
Probably the most interesting error I had to troubleshoot since I started developing my first Windows Metro application happened to me after doing some restructuring and cleaning up of the existing code base.
It seems that Visual Studio 11 Beta works better and more reliable in Windows 7 than it does in Windows 8 Consumer Preview. In Windows 7 I've been running it without problems, using Slovenian regional settings. In Windows 8 Consumer Preview on the other hand it doesn't even start properly when regional settings are set to Slovenian.
Windows Workflow Foundation (WF) is an often overlooked part of .NET framework but its declarative approach to defining workflow logic can prove useful in spite of the steep learning curve and some unfortunate limitations. Once you get to know it, you might even come up with new creative ways of using it.
Posts in February 2012
If you're using Subversion in a corporate environment you might need to rely on path based authentication to revoke users' read or write access to parts of a repository. Unfortunately the feature is not documented very well and there are a couple of specifics you should be aware of in advance to prevent unpleasant surprises later. I decided to describe two of them that I recently stumbled upon.
Last week I was configuring the build server to compile its first Visual C++ 2010 project. I took the approach of using MsBuild on the project file (.vcxproj) as I am already doing it with the .NET projects. This worked just fine on my development machine with Visual Studio 2010 installed. It soon turned out not to be as easy as I expected it to be.
Posts in January 2012
The more there are developers committing changes to the project source code and the more distributed they are, the more challenging it becomes to keep track of all the changes. Introducing a source control monitor notifying code owners of changes can be a good way to reduce this risk. Although there are dedicated tools available for this task, this post introduces a simple way to use your existing CruiseControl.NET setup for this task.
NuGet is a valuable tool for managing references to external libraries in your projects. If you're not using it yet, you owe it to yourself to try it out and see what you're missing. Though, that's not what this post is about. Not only are NuGet packages a great way to distribute publicly available libraries, they can be used just as well for custom internal libraries with their own release management which are used in multiple projects.
Web.config transformations are a great but often overlooked feature introduced with ASP.NET 4.0. They provide a simple way to define a different configuration for Debug and Release builds of your project by only specifying the differences (typically only connection strings and similar settings) in a separate transformation file while keeping the core of the configuration file common and consequentially making it easier to manage.
Posts in December 2011
DateTime can be a tricky data type to deal with. Not only is there daylight saving time and different time zones to keep in mind but also the range and precision can vary in different systems. You are probably already aware of some differences between .NET framework's DateTime structure in Transact-SQL's datetime data type. You might not be aware of the difference in precision between these two data types, though.
In a previous post I addressed the issue of using HTTP module based authentication in WCF. The presented solution worked in most cases but failed completely with Windows authentication. In this post I'll describe the necessary changes to make this work as well.
WCF has great built-in support for most types of authentication so there aren't many good reasons to use HTTP module based authentication with it. Having an existing ASP.NET application already using such authentication certainly is one of them. Finding resources on how to do it might be a challenge though. I managed to stumble upon an article by Microsoft patterns & practices team which helped a lot. In a way this post is its abridged and more practical version.
DefaultModelBinder is an essential piece of ASP.NET MVC framework which makes writing strongly typed actions really simple. In spite of its strengths it can still introduce hard to solve problems in your code.
Posts in October 2011
This year's Bleeding Edge conference was taking place this week in the beautiful surroundings of Gozd Martuljek. The second day was dedicated to community driven redelivery of Build. As the last session of the day I had a talk on the aspects of reusing existing .NET framework code in Metro applications for Windows 8.
Posts in July 2011
Reflection is a great tool for calling methods on objects when their types are not known at compile time. Unfortunately the Type.GetMethod method doesn't work with generic methods, therefore we need to find the right method by iterating through all the methods returned by Type.GetMethods. Searching for alternatives I stumbled upon a solution using expression trees. It got me wondering though, which of the two solutions actually performs better.
Posts in June 2011
XmlSerializer is often a great choice for persisting objects or transmitting them over the wire, either by using default object serialization tailored only with attributes or by implementing the IXmlSerializable yourself. If you're not careful though, this might come at a significant performance cost.
One of the features introduced in Entity Framework 4 was support for foreign key properties in entity types. If you decided not to include them in your model when you originally created it, but want to add them at a later time, you'll have to do it by hand. I'll describe the steps on a simple example.
Posts in May 2011
This week the annual Microsoft conference NT konferenca 2011 was taking place in Portorož. On Tuesday I had a talk there about the Windows API Code Pack. As promised, you can find the slides from this talk on SlideShare.
Posts in March 2011
It seems that no matter how much experience one has with .NET framework, there are still surprises awaiting him somewhere down the road. This time I'd like to point out an interesting behavior of MethodInfo.Invoke many of you might not be aware of. I certainly wasn't, until today.
When architecting solutions using Workflow Foundation it is typically necessary to provide information to individual activities. But apart from standard input arguments being passed to the workflow or originating from previously executed activities, which can best be modeled using InArgument<> properties, there is often also a need to access some kind of contextual information in the activity. In this post I'm going to discuss three different approaches to providing such context to a custom workflow activity.
One of the changes in .NET Framework 4 was the retirement of Code Access Security (CAS). Until recently this was something, I have only read about at the time of release, but it didn't have any effect on my day to day work. Therefore I was even more surprised that an application which has recently been migrated from .NET 2.0 to .NET 4 suddenly failed to start from the network drive while working flawlessly from the local machine.
Posts in December 2010
My favorite environment for running NUnitunit tests during the development process is definitely Unit Test Runner in CodeRush. When I just recently had to get a usable development environment up and running with Visual C# 2010 Express, I had to find a different solution since extensions are not supported in the Express SKUs of Visual Studio.
Posts in November 2010
While reading an article on the difference between const and readonly it surprised me that changes to public consts in the referenced assembly don't affect the referencing assembly unless it is recompiled using the changed referenced assembly. The C# Reference doesn't hint at such behavior at all, which means it's time for further exploration.
Recently I tackled a seemingly simple task: XML serialization of a generic class used with a TimeSpan data type. It turned out that XmlSerializer doesn't serialize the TimeSpan structure at all.
Posts in September 2010
Using information schema views and the fn_listextendedproperty function I wrote a table valued function which returns information about all the columns in the given table. I'm posting it here in case someone else finds it useful.
Trace listeners are a great mechanism for troubleshooting and monitoring applications in production environment. What I didn't know until recently, is that by adding a trace listener to your application you can cause it to crash.
Posts in August 2010
Since version 1.5 CruiseControl.NET includes an FTP Task which can be used for uploading build results to a remote FTP server. Configuring it correctly requires some thought and at the moment there are very few helpful resources available.
Posts in July 2010
Recently I've been solving some issues with queue starvation in CruiseControl.NET. Since I haven't found much information about this problem I've decided to round up my findings in this blog post.
Posts in June 2010
A few months ago I worked on a small spare time project which included some manipulation of binary Excel (.xls) files. This seemingly simple task soon turned out to be quite a challenge if you want to handle it right. The post you are reading is a short summary of my experiences. They should make your choices easier if you are about to tackle a similar problem.
Posts in May 2010
Subversion and CruiseControl.NET can be invaluable tools in your .NET development process. There are many resources available to help you get started which I'll try to gather in this post along with some of my personal experiences.
Posts in April 2010
Query parameters are a very useful Excel feature allowing parametrization of database queries used to import data in Excel. Unfortunately there is a limitation for using this functionality which turns out pretty unintuitive in Excel 2007.
Posts in August 2009
Microsoft Exchange supports Send As and Send On Behalf Of permissions to be granted to users for individual e-mail addresses. Sending e-mail from Outlook for these users is very simple. If you want to achieve this from code there is a little more work involved.
There is a away to identify an unrecognized device from the information available in Device Manager.
Posts in July 2008
Gama System eArchive, one of the two products in our document product line, received accreditation from the Archives of the Republic of Slovenia last week. This acknowledgment by our national body means that any document stored in Gama System eArchive is automatically legally valid.
Posts in June 2008
After taking my new hand-held GPS device for a test run, I decided to use Microsoft Pro Photo Tools which have just been released with geotagging as its main feature. Unfortunately it had problems loading my GPS data from GPX XML format.
Posts in April 2008
.NET Framework 2.0 Service Pack 1 caused the C# compiler in Visual Studio 2005 and later to set the NXCOMPAT bit for all build targets without an option to turn this new behavior off. This means that DEP (data execution prevention) will kick in unless it is turned off completely in the operating system.
The MonthCalendar control's BoldedDates functionality doesn't appear to work properly on Windows Vista. The same code works just fine on Windows XP.
Posts in December 2007
The Xbox 360 Dashboard update released on 4th December 2007 added support for playing DivX and XviD videos natively. Unfortunately this only works for media played directly from the dashboard and not within Media Center Extender. The only thing left to do was to setup Windows Media Player media sharing.
Posts in November 2007
Close() must be called on a CompressionStream before you start reading from the underlying stream. Calling only Flush() is not enough in this case.
In my opinion RSACryptoServiceProvider class is seriously under-documented in MSDN. For future reference I'm listing the solution to two problems I had.
Unlike Word or Excel where the location of AutoRecover files is set in the options, PowerPoint does not have such an option.
Posts in July 2007
Once you start putting CruiseControl.NET to production use you'll sooner or later encounter the need for custom build tasks. Unfortunately there is not much information available on development of custom tasks.
The following line in a batch file will execute a command for each file in a directory.
Although a MSI file can be installed by double clicking on it in Explorer or by selecting install from the context menu, you might want to start from command line to include it in a script. I had to do some searching to find a way for setting a different installation directory than the default one.
The 22.214.171.12418 build of CruiseControl.NET has an error in `msbuild.xsl` file which causes an XslLoadException to be thrown when trying to view the MSBuild output in the web dashboard.
Posts in June 2007
If you need cheap and simple OCR functionality Microsoft Office Document Imaging Type Library (MODI) is a nice option if its requirements (Microsoft Office 2003 or later) and limitations (limited language support) don't bother you.
Posts in May 2007
Windows Vista unlike the previous versions doesn't have an option to enable or disable hibernation in the Power Option of Control Panel. If you end up with disabled hibernation, the only way to turn it back on is from a command prompt.
Any custom identity being used for an application pool in Internet Information Services 6.0 must be a member of the IIS_WPG group which grants it all the necessary privileges, otherwise IIS reports only Service Unavailable when the site gets accessed.
Posts in March 2007
In Windows Vista the default value for the Persist Security Info parameter of an ADO connection string has changed from True to False. You should be aware of this because it can prevent your legacy code from working properly under Windows Vista.
One of the first tasks on my to-do list after buying a new computer with Vista Home Premium edition was setting up Media Center Extender for Xbox 360 along with Transcode 360 to make my Xbox 360 a true multimedia device. Unfortunately the problems started immediately after setting up the Media Center Extender on my PC: MPEG streaming resulted in errors.
There seems to be a problem with updating Windows Defender when using Microsoft Update instead of Windows Update in Windows Vista. The problem becomes apparent when Windows Defender puts up a warning in the system tray that its signatures are not up to date.
Posts in January 2007
The functionality of the Run as context menu item is often an invaluable tool. The downside of this command is that unless you want to use the administrator's account, you have to enter the desired username every single time which quickly becomes tedious.
Posts in December 2006
Microsoft Office 2007 applications (at least Outlook and OneNote in particular) require Windows Desktop Search 3.0 to be installed for their built-in search capabilities to work fully.
I've recently passed the MCP exam 70-536: TS: Microsoft .NET Framework 2.0 – Application Development Foundation. I found the exam quite easy with only a few really nitpicking questions.
Since my last posting two new gadgets have been released: Slovenian Portfolio provides information from Ljubljana Stock Exchange, Slovenian Rates provides information on exchange rates from 4 Slovenian banks.
We have just released our first Sidebar Gadget – Slovenian Radio. The gadget features a centralized list of radio stations (retrieved from our server) and basic controls for selecting the station and adjusting the volume.
Posts in October 2006
Since gadgets are HTML applications and the Windows Sidebar uses Internet Explorer 7 to render them, I prefer running their code directly in IE7 during development.
I though I'd gather in one place all the useful links I found with information on development of Windows Sidebar gadgets.
I've gathered few issues that could be covered better in the documentation since I've been struggling with them for some time before I got everything to work as expected.
As soon as a pooled connection with enabled application role gets reused an exception gets thrown and its description is not really helpful if you're not aware of the problem: General Network Error. This happens because the security context of the connection doesn't get properly reset when it is closed.
Posts in September 2006
Don't use Configuration.Save in scenarios where users might only have read and write permissions for the configuration file.
ASP.NET offers several ways of mapping nice public URLs to cryptic internal URLs matching the actual implementation.
The following code returns the time when a web resource was last modified. Maybe it will be useful to someone.
Posts in August 2006
Once the number of projects in a solution comes up to thirty or more, most of the project related operations become really slow. It is something to have in mind when deciding how to group projects in solutions.
Although in Visual Basic 6 all string variables are inherently Unicode, the same is not true for the components that come with it. The best solution is to use the components from the Microsoft Forms 2.0 Object Library.
Posts in June 2006
DasBlog allows extensibility through macros. Documentation doesn't mention their development at all. Blog posts are probably the best source of information available on it.
While IIS 6 in Windows 2003 prevents the download of files with unknown extensions by default, IIS 5.1 in Windows XP allows downloading such files. This might be something you want to prevent.
Before using EventLog.WriteEntry for adding events to event log you should consider calling EventLog.CreateEventSource to make your application a valid source of events. Keep in mind though that you need administrative privileges for it to succeed, therefore it is best to call it at installation time.
If you want to view EPS images with IrfanView you need to have Ghostscript installed.
Essentially everything you need to implement plugins in your application is some way to dynamically instantiate classes at runtime. In COM world this was achieved by calling the CreateObject function. In the managed world you should use AppDomain.CreateInstanceAndUnwrap.
By default the Windows XP Welcome screen shows the users created through the control panel applet. You can change all that by setting up the correct values in the registry.
Either as a user or as a developer you have certainly noticed that sometimes the application just flashes in the taskbar instead of actually coming to the foreground when the SetForegroundWindow function is called. What you might not know is why and when this happens.
The default port number 3389 for RDP (Remote Desktop and Terminal Services) can be changed through a registry value.
Posts in May 2006
By switching from C# with P/Invoke calls to Managed C++ when implementing a managed wrapper for the ANSI C style library I stumbled upon, I wanted to avoid the tedious and error-prone task of writing the P/Invoke signatures for function calls and user-defined types for the structures they used. As a side result I also managed to avoid most of the advanced marshaling issues with complex data structures.
Due to tightened default security in Windows 2003 the file shares cannot be accessed without logon in a domainless environment even if both shares and folders are set up to allow access to Everyone. Many different suggestions for solving the problem can be found, I'm just adding my two cents to this confusion.
Trying to build a C++ project opened from a network share in Visual Studio 2005 might fail with a strange error. The problem only appears when the share host can't authenticate the user reading from and writing to the share.
Managed C++ is actually quite nice in the 2005 version. You probably still wouldn't want to use it if you could get away with C# or VB. But if platform invoke is giving you too many headaches, you might want to take a look at it.
For anybody else like me out there who hasn't done more than an occasional DllImport call or two, the following resources should help getting to grips with the PInvoke basics.
Posts in April 2006
SQL Server's common data type datetim` for both date and time values can be a source of quite some confusion. The decision on whether to store them separate or joined can depend on many factors, but sooner or later the need for separating or joining the date and time parts will arise.
Posts in March 2006
Using unit testing in real development environment isn't completely trivial. Pragmatic Unit Testing in C# with NUnit is a great book for everyone who wants to start with unit testing but just doesn't know how to do it.
The following query is a good starting point if you want to export the SQL Server Agent job history to a file and you're still using Enterprise Manager from SQL Server 2000.
Simple file sharing hides Security tabs on all Properties dialogs. You need to disable this feature to explicitly set permissions on any object in Windows Explorer.
Yesterday my TortoiseCVS client just kept performing the command for several minutes without failing until I canceled it. The program responsible turned out to be NOD32 IMON service. In the end I had to exclude the CVSNT executable from the monitoring.
Posts in February 2006
To measure the time it takes to execute a piece of code before .NET 2.0, you had to develop your own high resolution timer by wrapping the unmanaged calls. Stopwatch class implements the same high resolution timer functionality out of the box.
No matter what you're doing in the static constructor, never allow it to throw an exception unless the problem is indeed fatal and you intend to quit the program immediately. In all other cases provide reasonable defaults and handle changed circumstances elsewhere in the code.
Security update 896358 prevents viewing HTML help (CHM) files from network drives. To avoid the repetitive tedious task of copying files to your local disk, you can set the maximum trusted zone in the registry to avoid the problem.
Posts in January 2006
When I started to work on my Master's thesis I first had to find a good source of articles from science magazines and journals and proceedings from conferences related to my research field. I decided to join ACM as a professional member and go for the additional ACM Digital Library subscription.
A web site redesign caused the structure to change, thus the old addresses become invalid. Since you don't want the users to get the dreaded error 404: Object not found, there are a couple of options available to you.
It's been almost three years since I last updated my web page and it's really about time to change that. I decided to use an existing solution for content management. I chose dasBlog since this site is about to become a sort of technology oriented blog. The most important thing is that I'll try to keep the updates more regular.
Posts in March 2003
I wrote my own application for managing the personal recipe collection. It features nice printouts, extensive search capabilities and simple entering of new recipes. It's only available with a Slovenian user interface.
Posts in February 2002
This project demonstrates the use of machine learning methods in real time navigation in unknown environment with given constraints. The archive also contains some sample data which directly demonstrates the really impressive results that where achieved with these methods and a quite extensive technical report in Slovenian.
Posts in January 2002
As a part of the Artificial Intelligence and Symbolic Programming course at university me and a group of fellow students got involved in a project which tried to achieve sensible tactical behavior of a group of soldiers controlled by a human player at a higher abstraction level.
During the Computer Vision course at university I designed a small program that recognizes time from images of a particular analog clock. The program along with sample images and complete source code is available for download.
Posts in August 2001
Tree Fractal applet interactively demonstrates how easy it is to construct interesting images by adjusting the fractal parameters. The archive contains complete source code, a jar archive with compiled classes and a HTML page for viewing in a browser.
Posts in July 2001
TV-Logo is a program for displaying logotypes of TV stations. To use it you only need a plain Amiga and a genlock to compose the Amiga output with the TV signal. The program offers easy switching among ten different source pictures for logotypes, ten preset logos available at a touch of a button and several other useful features.
Posts in February 2001
There probably isn't a computer user out there who hasn't heard of Java before. The language is already shipped with many ready to use classes and every release has more of them. I have written classes for some common tasks myself and you can download them from here for free.
Posts in December 2000
BallMaster is a puzzle game with a simple basic idea and (hopefully) addictive gameplay. It is based on an old game named Logical. This game tries to bring its idea to newer Amiga hardware and also tries to extend the original game with some new ideas.
Posts in September 2000
Blitz Basic is a simple but powerful programming language for Amiga. I've published some routines and techniques which might be of use to anyone who is still doing Amiga development in Blitz Basic.
Posts in July 2000
I have designed over 100 levels for Emerald Mines - a quality Amiga port of 8-bit gaming hit Boulderdash. You can download them for free. If you don't have an Amiga, you can use an Amiga emulator instead.