lessCode.net
Links
AFFILIATES
Tuesday
Aug222017

Xamarin Forms in Visual Studio 2017

I recently had a chance to revisit the latest state of cross-platform mobile development in Visual Studio. I haven’t been able to spend as much time as I’d have liked to have done in this area. The prospect of being able to architect a single application that can run under three different UI platforms (iOS, Android and UWP) is very compelling.

I have in the past built out applications, based on the Model-View-ViewModel separated presentation pattern, that were able to push about 75% of the code burden into shared models and view models that could drive separate WPF, Silverlight and (to a more limited extent) ASP.NET MVC UI implementations. Unfortunately, at that time Silverlight was already being regarded as a dead man walking, even for internal line-of-business apps. User interfaces are by far the least stable aspects of any application architecture, and UI technologies seem to evolve rapidly, so an architecture that can keep the UI layer as thin as possible is valuable for keeping ongoing maintenance costs in check.

Xamarin Primer

Xamarin was formed by the original creators of Mono (a cross-platform .NET CLR), and was acquired last year by Microsoft, which then quickly offered the Xamarin bits as a part of Visual Studio. Their are two versions of Xamarin “Native” (for iOS and Android), which allow for native apps on those respective platforms to be developed in C#. There is also Xamarin Forms, which is essentially a subset of UI components that can be used to build an application that can be deployed to both iOS and Android, in addition to Windows UWP “Store” apps (also on the Mac, but I’m not planning to try that). The apps are still native to each respective platform – this is not a “common-look-and-feel” proposition like you would have had back in the Java Swing/AWT days.

The Initial Xamarin Experience in Visual Studio 2017

Coming from a WPF background, I’m very familiar with XAML and MVVM, so I expected that Xamarin Forms app development would be fairly straightforward. For me there are some early annoyances and rough edges:

  • The ARM version of the Android emulator is painfully slow to start, deploy and run applications.
  • The x86 version of the Android emulator is faster (supposedly 10x faster - that’s not what I observed), but requires Hyper-V to be disabled and the machine rebooted, which is unfortunate because I have several other active projects that use Docker, and that requires Hyper-V to be enabled. If I’m going to be doing a lot of Xamarin work, I’m going to be rebooting a lot. I guess developers that are working on an app that uses a Docker-deployed back-end to a Xamarin Forms front end are going to need two development machines.
  • The iOS emulator won’t run at all unless you own a Mac and can connect to it on your local network. This is obviously not a big deal if you’re profiting from your application or have an employer or client that can foot the bill for an expensive spare device, but I’m not going to pay the Apple premium to experiment with Xamarin apps, so I concentrate mobile testing on Android.
  • After starting the Android emulator manually up-front, the empty sample project worked just fine, which was encouraging. Unfortunately, for some reason, after I closed the emulator and Visual Studio and came back to the project later on, it wouldn’t deploy to the warmed-up emulator: “… an error occurred. see full exception on logs for more details. Object reference not set to an instance of an object”. After uninstalling and reinstalling the Mobile development components in the Visual Studio installer, this went away and I was able to consistently run the app. No idea what happened there.
  • I hate to see warnings in the build output, and the empty Xamarin Forms project, out-of-the-box, shows several, which is sloppy QA. The first was complaining about a System.ObjectModel reference in the Android native project (it didn’t seem to matter when I removed the reference, so that’s probably an oversight of the project template). There were also several other warnings about the version of the Android SDK: “The $(TargetFrameworkVersion) for Xamarin.Forms.Platform.Android.dll (v7.1) is greater than the $(TargetFrameworkVersion) for your project (v6.0). You need to increase the $(TargetFrameworkVersion) for your project”. This is weird, because you’d think that the template would match the SDK references to the default version of Android targeted (6.0). Since I hate to see warnings in build output (did I mention that I hate to see warnings in build output?), I thought I’d take a stab at fixing those. I used the Android SDK Manager to install the 7.1 bits and then set the target Android framework to 7. Built OK, no warnings. Happy. Unfortunately it failed to deploy to the emulator, because aapt.exe crashed hard with no error messages. In hindsight, since the emulator is Android 6.0, I guess it should have been obvious to me that this wouldn’t work, but the tooling didn’t really help a novice out. I took a quick look around online for a 7.x version of the emulator for Visual Studio but wasn’t able to find one. I guess I’ll have to hold my nose and live with the warnings.
  • If you specify a DataType for a DataTemplate (so that you can eliminate Resharper warnings on bound properties) they don’t seem to render anything. No errors or warnings in the logs – your page simply stays blank. You have to leave your DataTemplate types open and ignore the squigglies. I hate squigglies.

I’m now looking at converting the PCL that represents the core Xamarin app logic into a .NET Standard library instead. This allows for a larger target surface area of the .NET API and simplifies the project files, but requires some manual work to convert (again I don’t see any tooling support for this yet in Visual Studio). Stay tuned for how that goes…

    Friday
    Jul142017

    Docker Support in Visual Studio 2017

    Having experimented with Docker on Windows about a year ago (on a Technical Preview of Windows Server 2016), I thought I’d take a quick look at how container support has evolved with the latest version of the operating system and dev tools. At the time the integration of Docker into Windows was fairly flaky (to be expected for such a bleeding edge technology), but I was able to get a relatively large Windows-dependent monolith to run inside a set of Windows Containers. Most of this involved crafting Dockerfiles and running docker commands manually (and eventually scripting these commands to automate the build process).

    Docker tools are now included in Visual Studio, so you can enable Docker support in a new (web) project when you create it:

    image

    Alternatively, you can add Docker support after the fact from the project context menu:

    image

    Either way, you get the following:

    • a default Dockerfile in your project. This is for packaging a container image for your service automatically.
    • a default docker-compose.yml file in your solution. This is for orchestrating the topology and startup of all of the services in your solution.
    • a docker-compose.ci.build.yml file in your solution. You can actually spin up a “build” container in order to run the dotnet commands to restore Nuget packages, build and publish (stage) your binaries and dependencies. This is great because now even the build process will be consistent across all developers machines (and the central build system), so in addition to eliminating the “runs on my machine” problem, it also alleviates any “builds on my machine” problems, where developers might have different tool versions or environment setup.

    The first time you run, there’s a significant delay while the appropriate image files are downloaded, but this is a one-time hit.

    Your service image contains a CLR debugger, which Visual Studio can hook up to, so you can step through your service code.

    What’s interesting (and not a little surprising) is that if you’re targeting .NET Core, your image will target a Linux base image by default. Docker for Windows also defaults to running containers in a Linux Hyper-V VM, so when you hit F5 the container will run your .NET Core service on Linux, and you’ll be remote debugging into a Linux machine.

    All very cool stuff, and works well right out of the box without too much fuss. Of course, you can also do all of this manually from the command-line if you prefer to develop in a lightweight editor like VSCode.

    Monday
    Jul102017

    Microsoft Azure Hybrid–At Last!

    From Reuters: http://www.reuters.com/article/us-microsoft-azure-idUSKBN19V1KQ

    I think many enterprises have been waiting for this for a long time, and will trigger a significant uptick in Azure usage. There are a couple of things about the cloud that instill resistance for enterprises:

    Privacy/Security/Regulatory. Especially in finance, and especially in European jurisdictions, there are often regulatory requirements around where data can physically reside, so in some cases the shared public cloud isn’t even an option. Even without regulations, putting sensitive data in the cloud has made enterprises nervous.

    Development cost. Unless you’ve demonstrated spectacular foresight and discipline with your application architecture (and you haven’t), there’s going to be some redesign work required in order to use the cloud effectively. That’s going to take a while to build and test, and you’re going to be paying for your cloud infrastructure through all of that as pure overhead until you go live.

    The ability to run some parts of your applications on the cloud and some on premises, yet still use the same tools, patterns and skillsets across both, largely dismisses these two hurdles. The holy grail is that you can keep your sensitive data and services locally on premise, while still taking advantage of the ability to scale up public-facing front-end applications, and for development and testing you can utilize a “local Azure”, running on hardware you own, that looks and feels like the shared public version, without incurring a significant cost overhead. When you’re happy with your solution, you can easily move the less sensitive parts to the public cloud, because it’s the same animal you’ve been using on-premise.

    I’m looking forward to experimenting with Azure again to see how flexible this hybrid approach is in reality.

    Thursday
    Jun292017

    Disappearing Scrollbar in Edge

    This has been bugging the hell out of me lately. I’m not sure when Edge started doing this, but it’s really quite annoying if you’re accustomed to using the vertical scrollbar on the right of the browser to “page” down or up by clicking the areas above and below the actual scrollbar “thumb” (the bit you can drag to scroll quickly). It doesn’t seem to happen on every site, it seems to be consistent on sites with content that spans all the way to the right-hand edge.

    When reading a long blog post or web page, I usually position the mouse pointer near the bottom of the scrollbar and click to page down through the article as I progress. Unfortunately, in Edge the scrollbar now entirely disappears after a few seconds of mouse inactivity, and doesn’t automatically reactivate on a mouse click – only when you move the mouse pointer completely off the area where the scrollbar used to be, and then back over to where it should be. I find myself constantly having to look over to the right in order to perform that little dance every minute or so. Very distracting. I guess I could use the keyboard for Page Up/Page Down, but on laptops nowadays you need to use the Fn key to get those, and I find a left-click more convenient.

    I wonder who thought this would be a good idea? I suppose there’s some non-mouse, non-desktop scenario (mobile?) where it makes sense, but on desktops it certainly violates the Principle of Least Astonishment, and since I don’t see any options to turn the behavior off, I guess I’ll have to live with it or switch back to Firefox…

    Thursday
    Jun222017

    Graph Databases and Neo4j

    My latest consulting project made heavy use of the graph database product Neo4j. I had not previously had an opportunity to look at graph databases, so this was a major selling point in accepting the gig. I had also suffered through some major pain with relational databases via object-relational mapping layers (ORMs), so I was keen to experience a different way of managing large-scale data sets in financial systems.

    I won’t (can’t) for various reasons provide a lot of detail about the specific use cases on this project, but I’ll put out some thoughts on the general pros and cons of graph databases based on several months of experience with Neo4j. I think I’m going to be using (and recommending) it a lot more going forward.

    What is a graph database?

    A graph essentially consists of only two main types of data structure: nodes and relationships. Nodes typically represent domain objects (entities), and relationships represent how those entities, well, how they are related to each other. In graph databases, both nodes and relationships are first-class concepts. Compare this to relational databases, where rows (in tables) are the core construct and relationships must be modeled with foreign keys (row attributes) and JOIN-ed when querying, or to document-store databases, where whole aggregates model entities and contain references to other aggregates (which usually must be loaded with separate queries and in their entirety in order to “dereference” a related data point). Depending on your use cases these queries can be complex and/or expensive.

    Why graphs?

    Performance. If your data is highly connected (meaning that the relationships between entities can be very fluid, complex and are equally or more important than the actual entities and properties), a graph will be a more natural way to model that data. Typical examples of highly connected data sets can be found in recommendation engines, security/permission systems and social network applications. Since all relationship “lookups” are essentially constant-time operations (as opposed to index- or table-scans), even very complex multi-level queries perform extremely efficiently if you know which nodes to start with. Graph folks term this “index-free adjacency”. Anecdotally, over the course of the last few months, with a database of the order of a hundred million nodes/relationships, executing queries that sometimes traversed tens of thousands of nodes across up to a dozen levels of depth, I don’t think I saw any queries take more than about 100ms to complete. For large result sets the overhead of transferring and processing results client-side was by far biggest bottleneck in the application.

    Query Complexity. Queries against graph data can be a lot more concise and expressive than an equivalent SQL query that joins across multiple tables (especially in hierarchical use-cases).

    What are the downsides?

    Few or no schema constraints. If you’re used to your database protecting you against storing data of the wrong type, or forcing proper referential integrity according to a strict data model definition, graph databases are unlikely to make you happy. Even a stupid mistake like storing the string version of a number in a property that should be numeric can lead to a lot of head-scratching, since the graph will happily allow you to do that (but won’t correctly match when querying). At first I thought this was a deal-breaker, but it’s not as big a problem as you’d think if you’re following test-driven disciplines and institute some automated tools for periodic sanity/consistency checks. You’re not waiting for a customer to find your query/ORM-mapping bugs at run-time anyway, right? Besides, a typical major pain point in RDMBS/ORM-based systems are schema upgrades as your rigid data model changes, especially when relations subtly change shape between versions.

    Hardware requirements. Optimally, in production you’re going to want a dedicated multi-node cluster where each node has enough RAM to potentially keep your entire graph in memory, so budget accordingly.

    Neo4j

    Neo4j is one of many graph databases (this technology is very hot right now and new ones seem to pop up every week). It is widely used by many large corporations and they are well ahead of the alternatives in terms of market share. I don’t want to give a full detailed review of Neo4j in this post, but their main selling points are:

    ACID compliance. Many NoSQL technologies sometimes can only offer “eventual consistency”.

    High availability clustering. Neo4j recently introduced a new form of HA called “Causal Clustering”, based on the Raft Protocol, which I haven’t yet had a chance to evaluate. At first I read this as “Casual Clustering” and had visions of nodes deciding arbitrarily on a whim whether or not they wanted to join or pull out of the pool or respond to queries… The older form of clustering replicates the graph across multiple physical nodes, and nodes elect a “master” which will be the primary target of all write operations. Non-master nodes can be load-balanced for distributed read operations.

    Integrated query language (Cypher). This is a very elegant and succinct (compared to SQL) pattern-matching language for graph queries. Statements match patterns in the graph and then act on the resulting sub-graph (returning, updating or adding nodes and/or relationships).

    Web interface. The interface is very nice and offers great visualizations of graph results. You can issue and save Cypher queries, perform admin-level operations and inspect the “shape” of your graph (i.e. what node labels and relationship types you currently have).

    Flexible APIs. There is an HTTP REST interface, but they also now offer a TCP binary protocol called BOLT which is much more efficient.

    Native Graph Model. Neo4j touts the purity of the graph model over other alternatives which attempt to mix and match different paradigms (eg. documents, key/value store and graph). I don’t have any direct experience of such “multi-model” databases, but I plan to compare Neo4j with other graph database products on a project in the future, so stay tuned.

    Extensibility. You can add your own procedures and extensions in Java (very similar to CLR stored procedures in SQL Server).

    Support. I can only speak to the enterprise-level experience, but Neo4j are very quick to respond to support questions and really stick with you until the problem is resolved.

    On the whole, I think graph databases in general, and Neo4j in particular, have a bright future ahead.

    Anyone else using graphs yet?