I’ve recently been working on a Xamarin.Forms project for Android and iOS and recently came across an issue that took some experimenting to get fixed so I thought I would share it for anyone else that might run into it.

Realm is a database designed for mobile applications and offers a safe, easy, non-ORM replacement for SQLite. The intent is that you can, for the most part, mark your data model objects as RealmObjects and Realm will handle all of the persistence for you. As with anything, it gets more complicated than that but so far it’s still much better for what I’m doing than SQLite. If I needed the ability to do offline synchronization with an online data source, I’d be looking at Azure Mobile Apps , but as I don’t I’m fine with what Realm will do for me.

Adding Realm to your Xamarin.Forms application just requires adding the Realm NuGet package to your projects. From there, you should be able to compile your projects without any issues.

However, if you have Continuous Integration set up to auto-build your projects and run tests with every build, it’s possible to run into an issue. I use Visual Studio Team Services to build all of my mobile projects and then deliver them to HockeyApp for beta testing. I’ll have to post more about setting up the Build Definition (the steps for building and uploading my compiled applications) but want to focus on the issue that having Realm in your projects has with the build process.

When you add Realm to your projects, it adds a Target as part of the package.
That step, called CopyRealmWeaver which copies RealmWeaver.Fody.dll as part of the build process. I won’t get into what Fody is but it’s a necessary part of using Realm. The XML found in the Realm.targets has the following inside of it:

<Target Name="CopyRealmWeaver" BeforeTargets="FodyTarget">
  <Message Text="CopyRealmWeaver" />
  <Error 
    Text="Solution directory was not set. If you are building via xbuild, specify by adding a /p:SolutionDir=/path/to/solution/folder argument. See github.com/realm/realm-dotnet/issues/656"
    Condition="'$(SolutionDir)' == ''" />
  <Copy SourceFiles="$(MSBuildThisFileDirectory)../tools/RealmWeaver.Fody.dll" DestinationFolder="$(SolutionDir)/Tools" />
</Target>

What this does is check to make sure $(SolutionDir) has been specified as part of the call to xbuild, or in the case of VSTS, msbuild. Provided that value has been specified, it then copies the RealmWeaver.Fody.dll from a tools directory in the packages folder into the Solution directory.

What’s wrong here

The problem here is that when compiling with VSTS, there is some step that changes the SolutionDir value to *undefined*. When I ran into this, it was especially weird as I couldn’t seem to find a reference to VSTS, build, and *undefined* anywhere. I did find a Stack Overflow post about Visual Studio replacing $(SolutionDir) with *undefined* which wasn’t the solution to my problem exactly but did get me on the right path. From there, I took a look at the call to MSBuild to see what was showing up:

2016-12-13T19:23:38.1392477Z ##[command]"C:\Program Files (x86)\MSBuild\14.0\bin\msbuild.exe" "C:\a\1\s\src\Droid\MyApp.Android.csproj" /nologo /nr:false /dl:CentralLogger,"C:\a\_tasks\XamarinAndroid_27edd013-36fd-43aa-96a3-7d73e1e35285\1.1.1\ps_modules\MSBuildHelpers\Microsoft.TeamFoundation.DistributedTask.MSBuild.Logger.dll";"RootDetailId=39592de0-fb1c-4156-a73e-b2e8ee77129e|SolutionDir=C:\a\1\s\src\Droid"*ForwardingLogger,"C:\a\_tasks\XamarinAndroid_27edd013-36fd-43aa-96a3-7d73e1e35285\1.1.1\ps_modules\MSBuildHelpers\Microsoft.TeamFoundation.DistributedTask.MSBuild.Logger.dll"  /p:configuration="Release" /p:_MSDeployUserAgent="VSTS_db204fe6-401b-4488-b9c9-02229bdeafd2_build_25_317" /t:PackageForAndroid /p:OutputPath="C:\a\1\b/Release" /p:JavaSdkDirectory=" C:\Program Files (x86)\Java\jdk1.8.0_102"

What I want to highlight from that call to msbuild is SolutionDir=C:\a\1\s\src\Droid. It seems like we’re specifying a Solution Directory, but the error shows us that somehow, that is being overwritten. So we need to override that overwrite and ensure a value is in fact being passed in.

Build Xamarin Additional Arguments

Thankfully, the Build Xamarin project build step has a spot for Additional Arguments at the bottom. In this case, I set the solution directory to the directory of my overall solution file and where the tools directory containing the RealmWeaver.Fody.dll is at. The format of the argument is important so this is what you should be using (adjusting the path for your) tools folder location of course:

/p:SolutionDir=”src”

With that done, I was able to run builds without any issue. This seem to be an Android only issue so you shouldn’t need to change anything on your iOS build.

Update 2-16-2017: A new error

After a recent update (to my code base), I found that my workaround was no longer working. The new error I was seeing was:

FodyTarget:
  Fody: Fody (version 1.29.4.0) Executing
  Fody: ProjectDirectory: 'D:\a\1\s\src\MyApp\MyApp.PCL\'.
  Fody: AssemblyPath: 'D:\a\1\s\src\MyApp\MyApp.PCL\obj\Release\MyApp.PCL.dll'
  Fody: Found path to weavers file 'D:\a\1\s\src\MyApp\MyApp.PCL\FodyWeavers.xml'.
##[error]Fody: SolutionDir "D:\a\1\s\src\MyApp\MyApp.PCL\src" does not exist.

What this appears to be doing is adding the SolutionDir that I specified above to the end of the PCL’s path. I was able to fix this once again by changing my Additional Arguments to:

/p:SolutionDir=”/”

I suspect this was due to a change in the Realm.targets XML file for the newer version of Realm that I updated to when I updated NuGets.

Azure edit

Today I’m excited to announce that we’ve released the Azure Usage and Billing Portal as an open source project on GitHub. The Azure Usage and Billing Portal is a solution which enables you to review the usage and resulting billing information across multiple subscriptions. Currently, if you are an Azure consumer using multiple subscriptions, you’re options for viewing all of the usage over any given time period aren’t that great. The Azure Portal enables you to view usage and billing for individual subscriptions one at a time (both a breakdown of current charges, cost by service, and cost by resource) but if you’re using multiple subscriptions, trying to review all of the information there is inefficient. Furthermore, you are able to download a CSV file of Azure consumption for each subscription, but that is a manual process and would require processing afterwards.

Last year, Microsoft announced new APIs to provide a way to programmatically pull information on usage and rate cards for your subscriptions. Included in that announcement were a number of samples demonstrating how you can pull information for your own subscriptions. When this announcment came out, we had already been seeing requests from customers we were working with for a way to visualize and track their spend. This spurred my team into action to build something which would make consuming and seeing this data easier.

Once deployed, you can now register any subscriptions you want so that the daily usage will be polled and displayed in an easy to use Power BI dashboard. This dashboard enables you to slice data in many ways including by subscription, by resource type, by resource name, by geo, by date, and more. Furthermore, you can use the SQL Database that stores the usage and billing to build any sort of interface / alerting on top of the data you want.

Mustafa Kasap, the lead engineer on this project, wrote up a great blog post describing the project a bit more including some helpful images.

We’ve got a lot of plans for future feature additions and already a few issues to fix. We welcome any contributions or feedback on the project either on the blog posts or as issues on the GitHub site.