{"version":"https://jsonfeed.org/version/1.1","title":"Dan Siegel | Building Better Apps","home_page_url":"https://dansiegel.net","feed_url":"https://dansiegel.net/feed.json","description":"Practical writing about .NET, .NET MAUI, Uno Platform, Prism, developer tooling, open source, and building maintainable software.","authors":[{"name":"Dan Siegel","url":"https://dansiegel.net/about/","avatar":"https://dansiegel.net/images/dan-siegel.webp"}],"language":"en-US","items":[{"id":"https://dansiegel.net/post/2023/10/07/prism-9-0-preview-1","url":"https://dansiegel.net/post/2023/10/07/prism-9-0-preview-1","title":"Prism 9.0 Preview 1","summary":"Ok I know I might start sounding like Tim Cook \"This is the biggest release yet\". But seriously, Prism 9.0 just may be the biggest release the Prism team has...","content_text":"Ok I know I might start sounding like Tim Cook \"This is the biggest release yet\". But seriously, Prism 9.0 just may be the biggest release the Prism team has done to date. Despite some people claiming Prism is dead because there wasn't a recent release, the fact is we were hard at work on this release. Prism 9.0 is the sum of 2 years of work and I think you're going to really like some of the changes. It grew to a point for many reasons that meant there would be no 8.2 and instead we had to bump to 9.0. So what is so different in this release?  \n  \n\n## The License\n\nOk this may not quite fall under the category of we were super hard at work. But at the same time it actually kind of does. The license has changed from previous versions of Prism. First and foremost I'd like to address the \".NET Foundation issue\". Both Brian and I love the idea of the .NET Foundation. We have always been big believers in it's initial vision and goals. Over the years though we simply realized that the vision of the .NET Foundation and it's actual practices (where it's really going) are two very different places. We believe in Open Source Sustainability, and fostering healthy relationships of trust between maintainers and the .NET Community. Unfortunately for a number of reasons we felt it was time to leave. \n\nAs I mentioned, we believe in Open Source sustainability. As you may be aware Brian and I were also early adopters of the GitHub Sponsors program and have tried for the last several years to build a sustainability model around Prism with it. GitHub Sponsors had amazing promise, unfortunately it just isn't something that is working. After years of going back and forth on this issue, we have finally decided to change the license to a Dual License model. If you are familiar with the Community License program that is available from Syncfusion then you will already feel at home with what we are doing. If you qualify for the Community License you do not need to sign up for anything and you can continue to use Prism for personal or commercial purposes completely for Free! For more information on the licenses please visit [prismlibrary.com](https://prismlibrary.com/).\n\n## One API To Rule them All\n\nPrism 9.0 represents a major shift for us moving forward. In the past we had Regions, and Modularity duplicated in WPF and Xamarin.Forms. Then of course we introduced Dialogs and duplicated these as well. To make it more fun we added support for Uno Platform and you had the community project for Prism.Avalonia each with their own interface definitions for what these APIs should look like and going from one to another you ultimately had some small breaks in the API. While we had actually moved the Modularity interfaces to Prism.Core in Prism 7.1, Dialogs and Regions have now moved to Prism.Core as well. This means for the first time you can write ViewModels for your Dialogs or Regions and reuse them from your WPF application to your .NET MAUI application or even your Uno Platform application. We believe this will greatly empower some amazing scenarios for developers who may want to reuse legacy code from their WPF applications and bring it forward to mobile platforms.\n\nNote that this also represents a break in namespaces as we are now sharing the NavigationParameters between Xamarin.Forms/.NET MAUI Page Navigation and Region Navigation. We have also moved the IDialogService to a new namespace as well.\n\nAlso well worth noting is that the IEventAggregator has been moved into a separate package which is now referenced by Prism.Core. This will enable people to make use of the IEventAggregator even outside of a Prism Application. Similarly we have moved our Dependency Container abstractions out of the Prism repo to a new private repo where the containers are maintained. This results in better sharing of DI Containers between platforms because they are now implemented independent from the platform meaning if you need specific container access without adding a framework dependency on WPF or .NET MAUI, etc... you now have this ability. This move also gave us the space to provide support for 2 new Dependency Injection Containers which will be available to Commercial Plus license holders ONLY.\n\n\\- Microsoft.Extensions.DependencyInjection  \n\\- Grace\n\n## .NET MAUI\n\nPrism 9.0 represents the first real release to support .NET MAUI. I know many people have wanted to see this a lot sooner, but truth be told .NET MAUI just wasn't production ready prior to .NET 8. With .NET 8 we finally got some of the API updates that we needed to properly support .NET MAUI and I think you are going to like it. For those who haven't yet had a chance to play with the earlier previews, Prism.Maui represents a change in paradigm where you no longer have a PrismBootstrapper or PrismApplication. We met the MAUI API where it made the most sense, with the MauiAppBuilder. This means that the flow is natural and you get a PrismAppBuilder with a fluent API that just makes sense. This also brings a number of changes to the table including a new NavigationBuilder that gives you more power and flexibility in creating your Page Navigation Uri's and even adds support for ViewModel navigation.\n\n## Uno Platform\n\nThis release adds support for Uno Extensions out of the box targeting the latest stable release of Uno Platform.","date_published":"2023-10-07T09:36:00.000Z","date_modified":"2023-10-07T09:10:45.000Z","tags":[".NET",".NET MAUI","Prism"]},{"id":"https://dansiegel.net/post/2022/06/02/prism-for-net-maui-public-beta","url":"https://dansiegel.net/post/2022/06/02/prism-for-net-maui-public-beta","title":"Prism for .NET MAUI - Public Beta","summary":"Ok the name kind of gives it away, but Prism for .NET MAUI is now available as a Public Beta! We've been working hard the past year on Prism for .NET MAUI, and...","content_text":"Ok the name kind of gives it away, but Prism for .NET MAUI is now available as a Public Beta! We've been working hard the past year on Prism for .NET MAUI, and at times it felt almost impossible as every time I would catch up with the MAUI team there would be new breaking changes that made it all pointless... The great news is that .NET MAUI has finally reached a certain level of API stability and we've been able to make some incredible process along the way. You might be asking, \"Isn't this really just Prism for Xamarin.Forms but built against .NET MAUI?\"\n\nThe answer to that is a little complex, but in short the answer is Yes... and No... The Prism.Maui initiative started with the Prism.Forms codebase and then over the past year we've made one improvement after another really in one of two categories:\n\n1) .NET MAUI had a change in API or Paradigm that required a change in how Prism handles \"....\"\n\n2) Prism.Forms was great but we really wish that we could have made \"....\" change\n\n![Prism for .NET MAUI - Public Beta](/images/blog/prism-for-net-maui-public-beta/01-image.webp)\n\n## Application Startup\n\nOne of the first things that you'll notice when you create a new .NET MAUI project is that you no longer have multiple Platform Heads with a common core project that contains your shared business logic. Single Project is here and it really cleans some things up. With Single Project we also get the MauiAppBuilder which is modeled after the App Builder pattern we've seen across the .NET Ecosystem from Console Apps to AspNetCore. This change is rather significant for developers coming from Prism.Forms as it moves the App Startup Logic outside of the PrismApplication and into the new PrismAppBuilder. One of the great things about the AppBuilder is that you get the opportunity to easily see what configuration options Prism offers and even get a few overloads to match what you need to do. In fact this gives you the opportunity to even write your own extension methods for the PrismAppBuilder as you can potentially call methods on the App Builder multiple times allowing you to split up your logic around what you might need to Register or Initialize. \n\n```csharp\n// It's as easy as...\nMauiApp.CreateBuilder()\n    .UsePrismApp<App>(prism =>\n        prism.RegisterTypes(c => {\n            // register your types\n        })\n        .OnAppStart(\"MainPage\"))\n        .Build();\n\n// Or take control of your navigation\nMauiApp.CreateBuilder()\n    .UsePrismApp<App>(prism =>\n        prism.RegisterTypes(c => {\n            // register your types\n        })\n        .OnAppStart(async (container, navigationService) => {\n            var result = await navigationService.NavigateAsyc(\"MainPage\");\n            if(!result.Success)\n            {\n                // use the container to resolve a logger\n            }\n        })\n        .Build();\n```\n\nThe `PrismAppBuilder` doesn't stop there though as we also make it easier to maintain a fluent API and try to meet you where you want to be. This means that instead of having to access the `ILoggingBuilder` or `IServiceCollection` off of the `MauiAppBuilder`, we give you easy to use extensions to provide your delegate. Not only did we do that, but we also made sure that if you need to use the `IServiceCollection` to register your services, you can easily access the same registration methods to register your Views for Navigation with the IServiceCollection.\n\n### Service Registration\n\nFor years Prism simply relied on 3rd party DI Containers. Due to issues surrounding different APIs with different containers, we began creating a robust container Abstraction layer that was powerful enough for most power users without needing to directly use the underlying container. We're rather proud of what this has unlocked for many developers. MAUI though brings Microsoft.Extensions.DependencyInjection into the Application Framework as a First Class citizen for the first time. While the Prism DI Abstraction layer isn't going anywhere, we did feel it was important to support both IContainerRegistry and IServiceCollection for registering your services.   \n  \n**NOTE:** Prism does not at this time directly support Microsoft.Extensions.DependencyInjection. There are limitations of the container which currently make it incompatible with Prism.\n\n## Navigation\n\nOver the years I've been incredibly blessed to travel to some amazing places and meet developers around the world. Without a doubt no matter where I go, everyone's favorite feature is Prism's awesome URI based Navigation for Prism.Forms. This was something that had to just work, but I also knew there was some room for improvement here as well. One of the first things was that the interface was cleaned up exposing only 3 methods with everything else being an extension method.\n\n### ViewModelLocator\n\nPrism has long had an Attached Property from the ViewModelLocator which allows you to optionally provide a boolean to Autowire the ViewModel. In early versions of Prism 6 this was required, however it was later made a Nullable Boolean with an assumption that if you had not set the property you probably wanted to Autowire the ViewModel. Prism.Maui changes this ever so slightly by introducing a ViewModelLocatorBehavior enum. You can either leave it Automatic and Prism will Autowire the ViewModel once the View is ready, or you can disable it entirely. It's important to note that if Prism detects that your View has a Binding Context that isn't itself or a Parent we will not Autowire your ViewModel.\n\n### Navigation Builder\n\nThe Navigation Builder is brand new for Prism.Maui and something I think you'll really love. It is easy to use as an extension method on the INavigationService. The Navigation Builder has a number of helper methods to help you create complex Navigation URI's which can include parameters that are specific to individual Pages in your route, add a NavigationPage, or build a custom TabbedPage on the fly. Of course that's probably all things you've come to expect from Prism. For years I've often had developers request one thing over and over again with Navigation. They know that they shouldn't reference the View from the ViewModel as this breaks the MVVM pattern, and Prism hadn't offered ViewModel Navigation. This is something that you can now do with the NavigationBuilder.\n\n```csharp\nnavigationService.CreateBuilder()\n    .AddNavigationSegment(\"ViewA\") // use classic names\n    .AddNavigationSegment<ViewBViewModel>() // use ViewModel First API\n```\n\n### Overloaded Registrations\n\nPrism's classic `ViewModelLocationProvider` has long had a limitation where a Single View can only be registered against a single ViewModel. This was something that I set out to solve with Prism.Maui. As a result, Prism.Maui is the first platform from Prism to support Registering a single View with different names each mapped to a different ViewModel. This will unlock so many possibilities particularly in the Enterprise and I'm excited to hear how this helps some of you create some incredible experiences.\n\n```csharp\ncontainer.RegisterForNavigation<BillingPage, MonthlyBillingViewModel>(\"MonthlyBilling\");\ncontainer.RegisterForNavigation<BillingPage, SubscriptionsViewModel>(\"Subscriptions\");\n```\n\n### Global Navigation Events\n\nOne of the frustrations with the Navigation Service is that it has to be tied to a specific Page for context of where it will need to Navigate from. Over the years this has been transformed from a Transient to a Scoped Service which opens up a lot of possibilities when it comes to sharing the instance across types which may be resolved at different times such as the View, ViewModel, or even ViewModel for a Region within the Page. It also makes it harder to wire up a single handler to try to track the actual navigation stack or handle Navigation Errors. Prism.Maui has introduced a `NavigationRequestEvent` using Prism's tried and trusted `IEventAggregator`. You can hook up to this out of the box, or install the Prism.Maui.Rx package and get access to an `IObservable<NavigationRequestContext>` as part of the PrismAppBuilder pipeline.\n\n```csharp\nMauiApp.CreateBuilder()\n    .UsePrismApp<App>(prism =>\n        prism.RegisterTypes(c => { })\n            .AddGlobalNavigationObserver(x=>\n                x.Subscribe(context => {\n                    // Check for Navigation Errors\n                    // Update a local context for your current Navigation Uri\n                })\n            ));\n```\n\n## Region Navigation\n\nIt might seem odd to some, certainly it always has to me. Regions ARE how you navigate with Prism.WPF, and this was missing API for a very long time from Prism.Forms. When we finally did offer it, it was in a separate package. Region Support in Prism.Maui is built in from the start and its really first class as a result. A lot of work has been given to ensure that Scoped Services such as the INavigationService will be injected into your Region Views and ViewModels the same as they are in the parent Page's ViewModel. In fact if you Register a View with a Region and it is an Active View within the Region, the Region's ViewModel can even participate in classic Prism Navigation ViewModels getting the INavigationParameters for the Initialize, OnNavigatedFrom, OnNavigatedTo, and even Page Lifecycle events with Prism's IPageLifecycleAware interface.\n\n## F.A.Q\n\nQ. Is this Production Ready?  \nA. In general I would say anything serious with MAUI should wait for .NET 7. This is absolutely great for POCs.  \n  \nQ. Is Prism.Maui API complete?  \nA. No, it's probably about 90%+ but we are still missing a few things like our XAML Navigation Extensions, & the newer Dialog Service  \n  \nQ. Do I have to register my services with Prism's IContainerRegistry?  \nA. NO! You can choose whether to use IContainerRegistry or IServiceCollection... and ultimately you can use both if its easier for you.  \n  \nQ. There is a flash of the Splash Screen when I do an Absolute Navigation. Is this normal? Will it be fixed?  \nA. Yes that is due to a known bug in .NET MAUI. Hopefully it will be fixed and we won't have to hack to make Absolute Navigation work in the near future.  \n  \nQ. Is the API likely to change?  \nA. It's matured quite a bit, but I do think we're mostly stable. It is still a beta package so things could still change.  \n  \nQ. Will there be a Template?  \nA. Yes there will be... but as of this post there currently is not one. It is coming though and soon!\n\n## Where To Get It\n\nThe public beta is available now on [nuget.org](https://www.nuget.org/packages?q=prism.maui). For those who have stepped up as a GitHub sponsor you can access the latest CI packages on [Sponsor Connect](https://sponsorconnect.dev/).\n\nPlease help keep Prism a sustainable Open Source project and [become a GitHub Sponsor](https://xam.dev/sponsorDan) today.","date_published":"2022-06-02T07:22:00.000Z","date_modified":"2022-06-02T16:05:56.000Z","tags":[".NET",".NET MAUI","Prism","Xamarin","maui","Xamarin Forms",".net maui"]},{"id":"https://dansiegel.net/post/2021/07/07/making-devops-easy-with-mobile-buildtools","url":"https://dansiegel.net/post/2021/07/07/making-devops-easy-with-mobile-buildtools","title":"Making DevOps Easy with Mobile.BuildTools","summary":"It's been quite a journey if I'm honest. In fact as I look back over the last several years it's really crazy too look at what the Mobile.BuildTools has...","content_text":"It's been quite a journey if I'm honest. In fact as I look back over the last several years it's really crazy too look at what the Mobile.BuildTools has transformed into from it's humble origins as a collection of PowerShell scripts I was tired of rewriting every time I started a new app. The Mobile.BuildTools have continued to make developers lives easier with the last major release being exactly 3 years ago. Spoiler, the Mobile.BuildTools 2.0 does so much for you over what 1.x could do, I cannot hope to cover it all in a single blog post. It also means I had to put together a full docs site and json schemas for the configuration so that I could remember it all. If you haven't started using the Mobile.BuildTools yet, this package really is a must add for all of your Xamarin apps. While most of my followers know me for maintaining Prism, what you may not realize is that I also have a passion for proper DevOps. One of the beautiful things about the Mobile.BuildTools is that at the end of the day it just a collection of MSBuild Targets which means that everything that you do on your Local dev machine just works in CI without any special scripts or extensions to install into your Azure DevOps org, and it doesn't even matter which CI platform you want to use because it will just work! Of course before you ask, this is a build reference meaning that there are no extra assemblies getting added to your app bloating the compiled app size (unless you want app.config).\n\n## What is in 2.0?\n\nWhile Mobile.BuildTools 1.4 is awesome, truthfully there were a lot of processes that I still found to be a struggle, or at least more of a process than what they really needed to be. Perhaps one of the single greatest changes is that while the Mobile.BuildTools continues to be a collection of MSBuild extensions that make the build pipeline tailored to the DevOps processes that make your life easier whether you're building on your local machine or in CI, you don't need to understand anything about MSBuild, or csproj properties. With 2.0, you can now leverage a json first approach to configuring the Mobile.BuildTools.\n\n![Making DevOps Easy with Mobile.BuildTools](/images/blog/making-devops-easy-with-mobile-buildtools/01-image.webp)\n\nThe Mobile.BuildTools 2.0 is a nearly complete rewrite from version 1.4, and while certain features could probably get their own dedicated blog posts I thought it might be good to give a brief introduction to some of the amazing features and how they can help you out.\n\n## Application Settings\n\nFor those upgrading from 1.4, you're already familiar with the secrets.json and Secrets class generation. Over the years I've had a lot of discussions with developers using the Mobile.BuildTools and how they're using it. Obviously I've also had a lot of experience with my own projects and how I've needed to use the BuildTools to help my processes. It became apparent to me that this really needed a name change to more properly reflect how people use this class generation. There may be some client secrets that you want access to, but often times it's not super sensitive \"secret\" information like what scopes you're requesting from the OAuth provider, or the url for the mobile app service layer. \n\nAs I hinted earlier the configuration is all done with json. When you install the Mobile.BuildTools it will generate a buildtools.json in your solution root. The default configuration will enable a bunch of things for you, however Application Settings will not be one of them out of the box. So let's take a look at how this works.\n\n```js\n{\n  \"$schema\": \"https://mobilebuildtools.com/schemas/v2/buildtools.schema.json\",\n  \"appSettings\": {\n    \"AwesomeApp\": [\n      {\n        \"properties\": [\n          {\n            \"name\": \"SampleProp\",\n            \"type\": \"String\"\n          }\n        ]\n      }\n    ]\n  }\n}\n```\n\nIn the configuration we can establish 1 or more settings classes to be generated in 1 or more projects within our solution. There is a lot of great content further explaining how to configure this on the [docs site](https://mobilebuildtools.com/config/appsettings/configuration/ \"Mobile.BuildTools Application Settings Configuration\"). A distinct advantage that this provides is that you are now able to define what properties belong in a generated class, what the data type is, and circumvent the problems encountered on certain build hosts like Azure DevOps Windows agents which like to cast all environment variables ToUpper... Additionally because it's described here, this gives other developers that you may onboard a single place to go to to see what they will need to setup.\n\n## The classic app.config\n\nIn the early days as I began prepping for the Mobile.BuildTools 2.0 I had a discussion with Chase Florell about some DevOps issues that he had been facing with his team at the time. To be honest it's not an uncommon issue. The issue was effectively there was an easter egg in the app where you tap 5 times, spin around on one leg, while whistling dixie... if you've been around building Xamarin apps for a while you may have seen or implemented this exact sort of thing. The easter egg was there to allow testing with production builds so that you could effectively take a build for QA and test against production, or take a production build from the store and make sure that it won't break against some Dev / QA version of the app's service layer. In this scenario an app.config makes a lot of sense to use, particularly when you have the ability to perform live transformations in the app. While there are some other very valid reasons to want to use app.config, whatever your reason, the Mobile.BuildTools 2.0 now makes this possible with it's own implementation of the ConfigurationManager. This is entirely interface based meaning that for those of you who love DI as much as I do, you'll be able to register the current instance with your container and work against the interface making it easier to test your code. To use this you will need to install the [Mobile.BuildTools.Configuration](https://www.nuget.org/packages/Mobile.BuildTools.Configuration/) package.\n\n## Image Management\n\nOk a dirty little secret of Mobile app development... you will likely hate whenever someone says you need an image because you need about 40,000 different resolutions of that one \\*\\*\\*\\*\\*\\*\\* image. Interestingly both [Jon Dick (@Redth)](https://github.com/redth) and I seemed to have gotten fed up with this and began pushing for a better user story on these features about the same time. While Resizetizer is fantastic and built into Maui, there are some issues that I still saw that could be a lot better. The first issue is that most developers I talk to share with me that they either just don't understand MSBuild properties at all or they feel intimidated editing a csproj file. This of course circles back to why I created a json configuration file to begin with. Again for an in depth look at what the Mobile.BuildTools can do for you, be sure to [checkout the docs](https://mobilebuildtools.com/images/). In short some highlights you get with the Mobile.BuildTools are:\n\n-   Images do not need to live in any project\n-   You can include one or more folders containing image assets\n-   You can conditionally include images/image configurations based on the build Configuration or target platform (iOS/Android/UWP)\n-   Supports JPEG, PNG, & SVG source images\n-   Generate 1 or more output images. (handy for having thumbnail and full size versions)\n-   Add a padding to any image (handy for those circle icons on Android)\n-   Configure an image globally or have per platform overrides\n-   Image source and target names do not need to match\n-   You can add background colors to transparent source images (handy for those app icons)\n-   You can add a watermark graphic to any image (they don't even need to be the same size, the Mobile.BuildTools will resize appropriately for you!)\n-   You can add a custom text graphic to any image, with support for gradients, and full control over your colors and even what font you want to use (handy for having app icons with a banner like Dev, QA, or Lite, Pro, etc)\n\nBelow you'll see a sample of an image configuration for an app icon. When we build for iOS it will automatically pick up the AppIcon.appiconset, and generate all of the outputs defined in the json file for us. When we build for Android though it will generate 3 images for us. The first will be called icon and will be added as a mipmap resource. Next we'll get a launcher\\_foreground image, which will have a padding on it so that it displays nicely as a round image. Finally we'll get a copy of our original icon, but called notifications and will be available as a drawable resource instead.\n\n```js\n{\n  \"$schema\": \"http://mobilebuildtools.com/schemas/v2/resourceDefinition.schema.json\",\n  \"name\": \"AppIcon\",\n  \"android\": {\n    \"resourceType\": \"Mipmap\",\n    \"name\": \"icon\",\n    \"scale\": 0.1875,\n    \"additionalOutputs\": [\n      {\n        \"name\": \"launcher_foreground\",\n        \"resourceType\": \"Mipmap\",\n        \"scale\": 0.28125,\n        \"padFactor\": 1.5\n      },\n      {\n        \"name\": \"notifications\",\n        \"resourceType\": \"Drawable\",\n        \"scale\": 0.1875\n      }\n    ]\n  }\n}\n```\n\n## App Manifests\n\nFor your AndroidManifest.xml and Info.plist there are a couple of common issues I've always wished that could be easier. Luckily the Mobile.BuildTools makes it super simple now. By far the most common scenario every developer needs to address is App Versioning. Now with the Mobile.BuildTools you have a way to get your app to bump the version with every build. You can set this up to work only in CI environments, only outside of known build environments (your local machine), or everywhere. You can also set it up to use prefer a build number when available or use a timestamp. This means no extra build steps are required to bump the app version and no extensions like the [Mobile App Tasks from James Montemagno](https://marketplace.visualstudio.com/items?itemName=vs-publisher-473885.motz-mobile-buildtasks) for Azure DevOps. All you need to do is build and your app will automatically get a fresh app version!\n\nApp manifest manipulation doesn't always end there. There can be a variety of reasons why you might need to update values in your app manifest such as updating the app id based on the build environment (Dev, Stage, Prod). Other reasons could include scenarios where you're using Azure Active Directory B2C or similar OAuth library for user authentication and you either want to just make sure you're following good development practices by keeping the client id out of source control, or you need to specify different client id's based on build environment. Whatever your reason you can say goodbye to managing multiple copies of the manifest, or dealing with scripts and accidently checking in those changes to source control. The Mobile.BuildTools now allows you to tokenize your app manifest, and we will automatically search for and replace them based on values from your appsettings.json & environment variables. \n\n```xml\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\" android:versionCode=\"1\" android:versionName=\"1.0\" package=\"$AppId$\">\n\t<uses-sdk android:minSdkVersion=\"21\" android:targetSdkVersion=\"29\" />\n\t<application android:label=\"$AppDisplayName$\"></application>\n\t<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\" />\n</manifest>\n```\n\nFor scenarios like this which clearly are not sensitive in nature the Mobile.BuildTools has another helpful feature in the config. You have the ability to define constants for the build environment which exist within the buildtools.json and will be used in the event that they do not exist in the system Environment or appsettings.json, and you can even have these be conditional just like with Images!\n\n```js\n{\n  \"$schema\": \"https://mobilebuildtools.com/schemas/v2/buildtools.schema.json\",\n  \"environment\": {\n    \"defaults\": {\n      \"AppId\": \"com.avantipoint.buildtoolssample\"\n    },\n    \"configuration\": {\n      \"Debug\": {\n        \"AppId\": \"com.avantipoint.buildtoolssampledev\"\n      }\n    }\n  }\n}\n```\n\n## Next Steps\n\nLike I said there's a lot jammed packed into the Mobile.BuildTools, more than I could hope to go into depth on in a single blog post. It's designed to help simplify your DevOps processes by making it seamless between your local dev machine and CI build agent. Ultimately the best way to learn more is to get started by taking a look at the docs and adding the Mobile.BuildTools to your app.\n\n-   [Mobile.BuildTools docs](https://mobilebuildtools.com/)\n-   [Sample Apps](https://github.com/dansiegel/Mobile.BuildTools/tree/master/samples)","date_published":"2021-07-07T08:59:00.000Z","date_modified":"2021-07-07T18:20:03.000Z","tags":[".NET","Xamarin","DevOps","Xamarin Forms","Mobile.BuildTools"]},{"id":"https://dansiegel.net/post/2021/03/12/shiny-all-the-things-writing-testable-code","url":"https://dansiegel.net/post/2021/03/12/shiny-all-the-things-writing-testable-code","title":"Shiny all the things - writing testable code","summary":"Shiny all the things as they say. If you aren't using Shiny for your Xamarin.Forms or Uno Platform apps, the question is why? We see a lot of people excited...","content_text":"Shiny all the things as they say. If you aren't using Shiny for your Xamarin.Forms or Uno Platform apps, the question is why? We see a lot of people excited about UI libraries these days. While UI is always an important ingredient of any successful app, no app is complete without a resilient and testable architecture. This is one of the reasons why I use Shiny in all of my apps today. But what is Shiny, and why should you be using it?\n\n![Shiny all the things - writing testable code](/images/blog/shiny-all-the-things-writing-testable-code/01-image.webp)\n\nBefore we can look at that it's perhaps important to look at that thing that so many people fail to do... test your apps. Writing loosely coupled code is an important concept to master if you ever hope to write testable code. Using Test Driven Development is an important concept to help ensure that you speed up the development loop, and eliminate bugs, particularly in your business logic early. When we use loosely coupled code, using design practices that are intentionally Testable, and marry that with Dependency Injection we end up with an app architecture that is powerful, lightweight and robust. But what is Shiny? Is it true that it has a lot of overlap with Xamarin.Essentials? Why is it better to use Shiny than Xamarin.Essentials? How does Shiny help us build apps with loosely coupled testable code?\n\nThese are all great questions. While no single blog post could ever hope to fully explain these things in detail, hopefully by the end of this one you have a better sense for how to use Shiny to improve your app, write less code, and perhaps most importantly write tests that help you achieve your goals.\n\n### What Is Shiny?\n\nShiny is a collection of lightweight API's that help with common and specific requirements that many apps end up having to write complex solutions for. Between the Shiny Core and optional NuGet packages there are around 20 or so common things that Shiny will help with including Local Notifications, Push, Geofencing, GPS tracking, network Connectivity, foreground and background Jobs, and much more. By using Shiny you end up with lightweight, platform agnostic code that is written once instead of once for each target platform, and is ultimately easier to test.\n\n### Is it true that Shiny has a lot of overlap with Xamarin.Essentials? Why is it Better?\n\nI suppose this is all in the eye of the beholder. Shiny does indeed have some overlap, though both Xamarin.Essentials and Shiny have different goals and thus expose API's for different things. For example both have helpers that allow you to get things like the app Data directory or Cache directory path. Both have API's for determining the app's network connectivity state, and even Secure Storage. However Essentials will never try to deal with Bluetooth or Push notifications, while Shiny would never try to deal with Email, the WebAuthenticator, etc. \n\nBut this really brings us to the next question, why is it \"Better\"? Ok better might be a little harsh, and in full transparency I do quite often use Xamarin.Essentials together with Shiny as you'll see when we cover testing. Seriously though, why is Shiny often \"Better\" to use over Essentials? To answer that, we have to look again at the testability. Xamarin.Essentials has always taken the approach of Static API's that are cross compiled using a NuGet packaging technique commonly referred to as \"Bait and Switch\". What this results in is theoretical gain in performance at the sub-millisecond level (we're talking extreme tech geek level looking at bytes taken up in memory). In practice there is no practical gain in performance. However by referencing Xamarin.Essentials particularly from shared code you permanently loose the ability to actually unit test your code as the result is that your Unit Tests (running say netcoreapp or full framework .net) end up with the bait and switched version of the dll that simply throws a NotImplementedException or PlatformNotSupportedException... not really useful for testing your code. Even if you are running unit tests with a device runner on iOS/Android, you still end up with the problem that you cannot mock the return values of Essentials thus negating your ability to validate how your own code say handles various values you might expect. To get around this, you could simply use Xamarin.Essentials.Interfaces a community package from Ryan Davis that is generated for each release of Xamarin.Essentials, however there are still other benefits to using Shiny.\n\nSome of the notable benefits with Shiny is that it takes an interface first design approach. Additionally because Shiny uses Dependency Injection out of the box this means that you can instantly leverage what Shiny is doing and just simply inject the interfaces you require without having to register the interface / implementation or prevent the linker from stripping out the constructor of the implementation. Shiny additionally provides API's that are rich with an understanding of Reactive programming, providing you Observables over events which is much more powerful for scenarios like determining when the app is Online/Offline. For the sake of this article we won't go into that, but I would encourage you to learn more about Reactive programming if you have not already. Finally some of the API's such as Secure Storage are just easier to use, as we will see in a moment.\n\n### How does Shiny help us to write loosely coupled, testable code?\n\nThis is perhaps one of my favorite additions to Shiny v2, and honestly a feature I've been bugging Allan for since before the world changed with Covid-19. Shiny had always supported a concept of \"Settings\". These were things that you could implement a class for and through a little DI magic from Shiny, your class was instantly a persistent data store that you could provide settings values to and access them from one launch of your app to the next. So how did this work?\n\n```csharp\npublic interface IMyAppSettings\n{\n    string Username { get; set; }\n}\n\npublic class MyAppSettings : ReactiveObject, IMyAppSettings\n{\n    [Reactive]\n    public string Username { get; set; }\n}\n```\n\nThe first thing we're doing here is providing an interface that simply provides some setting like the Username of the user for the app. The interface is basic, it describes the properties we care about without any care in the world of the fact that we might be storing these values with some persistence. Next we implement this, and choose a base class that also implements INotifyPropertyChanged. For this example I'm using ReactiveUI's ReactiveObject, and adding the Reactive attribute to the property, because I'm lazy, and the ReactiveUI.Fody package will update at build with the actual getter and setter. Now in our Startup we simply can register this with the IServiceCollection calling AddSingleton and provide the interface and implementing class. Shiny does the rest ensuring that it is properly bound so that IMyAppSettings will persist from one launch to the next with our app.\n\nYou might also note here that this is quite different from using Preferences in Xamarin.Essentials, as our class is simply a normal class implementing INotifyPropertyChanged. There is literally nothing special about it.\n\nThis is great but sometimes we might want to protect the setting. An example of this could be with the user's session token that we'll use to authenticate with our app's API. We might normally want to use the platform Secure Storage, but using something like this with Xamarin.Essentials would be difficult to implement as easily. For starters Xamarin.Essentials exposes this with an async API which doesn't mesh well with binding to Getters and Setters. There is technically a reason for this, and one that to be transparent doesn't work well for those targeting UWP in particular. As a result the Secure Store isn't supported by Shiny on UWP (but you could write your own provider and submit a PR to Shiny), however if you're targeting iOS, watchOS, tvOS, macOS, or Android this will work for you. So how do we do this with Shiny v2? The answer is with a completely re-architected concept of Settings to Stores. This allows us to similarly bind our implementation like we did with Settings in v1, but now we can choose a specific Store for Shiny. Let's look at how we might do this with Shiny v2.\n\n```csharp\npublic interface ISessionStore\n{\n    string Token { get; set; }\n}\n\n[ObjectStoreBinder(\"secure\")]\npublic class SessionStore : ReactiveUI, ISessionStore\n{\n    [Reactive]\n    public string Token { get; set; }\n}\n```\n\nJust like with Settings from Shiny v1, we setup our interface and implementing class. Where it changes ever so slightly, is that by adding the ObjectStoreBinder attribute to our implementation and specifying the `secure` store Shiny will now transparently bind this to the SecureKeyValueStore when we register this with Shiny like:\n\n```csharp\npublic override void ConfigureServices(IServiceCollection services, IPlatform platform)\n{\n    services.AddSingleton<ISessionStore, SessionStore>();\n}\n```\n\n### How this helps us write tests and be more productive?\n\n\"Test driven development\", it's one of those phrases that we have all heard, but all too often fail to do. If you've been around the Mobile Development world for more than 5 minutes you've probably figured out that it can take significantly more time to build for your device than to simply build a netstandard or netcoreapp project. Since our code is generally in a netstandard project and our tests are likely a netcoreapp this means that when we're writing tests we can much more rapidly build and execute tests to validate that our business logic is executing as expected. For the purposes of this post, I will be showing some code examples with xunit, but any test framework is fine. I will also be showing this using Moq, which is another fantastic Open Source library for helping you write unit tests that I encourage you to learn more about.\n\nNow let's assume that we have an Authentication Service that will need to use the SessionStore we created earlier. The Authentication Service has a Login method, and will use the WebAuthenticator from Xamarn.Essentials. Remember we want our code to remain testable so we instead need to reference Xamarin.Essentials.Interfaces and inject IWebAuthenticator instead of calling the WebAuthenticator directly. Our Authentication Service might look like:\n\n```csharp\npublic class AuthenticationService : IAuthenticationService\n{\n    private ISessionStore _sessionStore { get; }\n    private IWebAuthenticator _webAuthenticator { get; }\n    private IAuthenticationConfiguration _authConfig { get; }\n\n    public AuthenticationService(ISessionStore sessionStore, IWebAuthenticator webAuthenticator, IAuthenticationConfiguration authConfig)\n    {\n        _sessionStore = sessionStore;\n        _webAuthenticator = webAuthenticator;\n        _authConfig = authConfig;\n    }\n\n    public async Task<bool> Login()\n    {\n        if (!string.IsNullOrEmpty(_sessionStore.Token))\n        {\n            // We might also want to validate the session hasn't expired...\n            return true;\n        }\n\n        var result = await _webAuthenticator.AuthenticateAsync(\n            _authConfig.AuthUrl,\n            _authConfig.CallbackUrl);\n\n        _sessionStore.Token = result.AccessToken;\n        return !string.IsNullOrEmpty(_sessionStore.Token);\n    }\n}\n```\n\nNow when we go to test this there might be a few things we want to validate. Because this is using an interface instead of the WebAuthenticator explicitly, we now have the ability to leverage the Moq library to create a mock implementation that can provide callbacks into our code, and even allow us to simulate different responses, or even exceptions such as the TaskCancelledException. Let's get started with our first test. For this we want to validate that when we have a token our Login method will immediately return a true value and not call the WebAuthenticator.\n\n```csharp\n[Fact]\npublic async Task DoesNotCallWebAuthenticatorWithValidToken()\n{\n    var store = new SessionStore\n    {\n        Token = \"SampleToken\"\n    };\n\n    var wasCalled = false;\n    var webAuthMock = new Mock<IWebAuthenticator>();\n    webAuthMock.Setup(x => x.Login())\n        .Callback(() => wasCalled = true)\n        .ReturnsAsync(new WebAuthenticatorResult());\n\n    var authService = new AuthenticationService(store, webAuthMock.Object, Mock.Of<IAuthenticationConfiguration>());\n\n    Assert.True(await authService.Login());\n    Assert.False(wasCalled);\n}\n```\n\nYou will notice that we can write a very clean test to continually validate that our AuthenticationService is ONLY calling the WebAuthenticator when we need. We've done with without any single reference to Secure Storage. While the Secure Storage may be a business requirement this is done in a loosely coupled way that does not impact or complicate our test in any shape way or form. Additionally because we're are creating our test cases here we can rapidly see if a change in code breaks our business logic, we can debug the test, and do so at a much faster pace than build, launch and stepping through out app just to hit our break point.\n\n![Shiny all the things - writing testable code](/images/blog/shiny-all-the-things-writing-testable-code/02-image.gif)\n\n### How you can get started with Shiny\n\nFirst and foremost I would encourage you to look at the sample app that is part of the [Shiny repo](https://github.com/shinyorg/shiny) (currently in the dev branch for v2). As you'll probably notice the sample leverages the power of building a loosely coupled app by additionally working with Prism and ReactiveUI/Rx principles. This shows how easy it is to build apps that combine the power of each of these libraries and frameworks to more quickly develop incredibly powerful apps. You can additionally choose to leverage the [Prism Container Extensions](https://github.com/dansiegel/Prism.Container.Extensions) with Shiny.Prism. For those who want to help make Open Source more sustainable you might also consider becoming a [GitHub Sponsor](https://github.com/sponsors/dansiegel) and leverage the incredible power of the Prism Magician via the Sponsor Connect package feed and additionally gain various code generators and Roslyn Analyzers to help you keep from making common mistakes while writing less code (since I do it for you). \n\n-   Check out the [Shiny repo](https://github.com/shinyorg/shiny)\n-   [Become a GitHub Sponsor](https://github.com/sponsors/dansiegel)\n-   [Inquire](https://avantipoint.com/?utm_source=dansiegel.net&utm_medium=shiny-all-the-things-writing-testable-code) about Enterprise support for your Prism apps","date_published":"2021-03-12T08:30:00.000Z","date_modified":"2021-03-22T14:45:16.000Z","tags":[".NET","Xamarin"]},{"id":"https://dansiegel.net/post/2020/12/22/source-generators-an-exercise-in-futility","url":"https://dansiegel.net/post/2020/12/22/source-generators-an-exercise-in-futility","title":"Source Generators an Exercise in futility","summary":"Some time ago I did a live stream with Jérôme Laban from the Uno Platform team on Source Generators. This actually predated a lot of the more recent excitement...","content_text":"Some time ago I did a live stream with Jérôme Laban from the Uno Platform team on Source Generators. This actually predated a lot of the more recent excitement with the Roslyn based Source Generators that are now generally available as part of Visual Studio 16.8. As I got to learn more about Source Generators I quickly learned just how powerful they are.. because I'm lazy and dislike manually doing more than I have to (most developers I know are the same way).\n\n<iframe src=\"https://www.youtube.com/embed/ju8aUa-clHs\" width=\"560\" height=\"315\" frameborder=\"0\" allowfullscreen=\"allowfullscreen\"></iframe>\n\nAmusingly out of our sheer laziness, we often have defaulted to falling back to runtime reflection. Of course there is a performance cost, that we generally like to dismiss because we can't build much more dynamic applications. To be fair this tradeoff also comes with some benefits for maintainability. With Source Generation though we can shift this reflective cost from the runtime to the build time. This means if we're going to pay a 1-2 second cost, let the developer or CI build take the hit instead of the app user every time they use our app. \n\nAs you may have noticed some of the runtime reflection that we added to Prism 7, rather suddenly was stripped out by Brian in Prism 8 after he learned about my side project the [Prism Magician](https://prismmagician.com/). The Magician was built using the techniques that I learned from Jérôme, along with a few other tricks I had up my sleeve. But hey the Roslyn team finally brought us Source Generation out of the box, so if we can get rid of a dependency why wouldn't we want to do that? Well get ready for the good the bad and the utterly WTF moments that come with that...\n\n## The Good!\n\nNaturally being something that is out of the box that just works is always a great thing. It's also fantastic that this builds on what we've already been doing, as we can now ship Source Generators as part of the same Roslyn Analyzers package that we may already be shipping, and at the very least we have a technique for packing these or including them in our project that is already being widely used. So far so good, no complaints right....\n\n![Source Generators](/images/blog/source-generators-an-exercise-in-futility/01-Picture1.webp)\n\n## The Bad...\n\nActually much to the Uno Platform team's credit with their Source Generation package, there is a recognition that there are a lot of common extensions you'll want/need when writing Source Generators. These come standard as part of the Uno.SourceGeneration package and are obviously not present when working directly with the Source Generators from the .NET team.\n\nNext up is actually just one of the general issues with Source Generation, which is that you're ultimately just using a string builder. While the Uno Platform team does give you an IndentedStringBuilder that you can use to more easily manage code indentation and blocks such as for namespaces, classes, methods, etc... again this is totally missing from the .NET team so you get an out of the box string builder. The good news on this front is that I do have a [CodeGenHelpers library](https://github.com/dansiegel/CodeGenHelpers) that you can include that really helps to more dynamically build your source code and generate clean output with a fluent builder approach.\n\n## WTF!!!!\n\nAs is often the case, docs and the actual API's are a bit out of sync to a point where the documentation literally says that you should expect behavior that was specifically dropped during the previews. Have fun with that one... So what is the behavior anyway? Well the behavior is that by default the Generators will not actually output the generated source to the disk. While the theory is that you can always navigate to reference, not all references will be in your code, and it can actually often be far more difficult than it should be to see what was generated, even where there are errors Visual Studio will generally not navigate to the Generated code. You can of course fix it if you know to add the following undocumented property to your project (the one consuming the generator). Note that adding this will add a generated folder in the temporary output (obj\\\\{targetframework}).\n\n```xml\n<PropertyGroup>\n  <EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>\n</PropertyGroup>\n```\n\nOk that's it, right??? Nope, not by a long shot... I did say earlier who wouldn't want to use the approach from the .NET team right... and after all as much as I love the work from the Uno Platform team, it's always nice to get rid of a dependency when you can (and when it makes some sense)... So I've spent the last few weeks working on a fairly significant rewrite of the Prism Magician so that it would do all of the Source Generation using the new Roslyn approach. It works marvelously on .NET Standard, and for both Xamarin.iOS and MonoAndroid targets.\n\nIt might seem like I've skipped a few targets. If you've been following me for a while you know I'm a maintainer for the Prism Library, and we love WPF and Uno Platform projects, and not just Xamarin.Forms. The Prism Magician is a fairly beefy solution, not so much because there are a ton of projects that need to get packed, but because there are about 16 test projects that test the Magician for Prism.Forms, Prism.Wpf, & Prism.Uno. So what happened?\n\nAfter finally completing the migration and getting all of the Prism.Forms projects stable, I was immediately blocked. While the generators did run for netstandard2.0 and Xamarin.iOS and MonoAndroid targets, no source was added for the UWP target in the Uno Platform test projects (although a generated folder was created). What's worse though is that the generators fail to run completely for WPF (you can track the issue [here](https://github.com/dotnet/wpf/issues/3404#issuecomment-682609361)). The issue has actually been know about since August but, hasn't exactly been discussed openly as a known short coming.\n\n## Final Thoughts\n\nSource Generators are amazing. For those of you building apps with Prism and who are able to target Prism 8, you should absolutely consider using the Prism Magician it will solve a ton of issues for you, and gives you a lot more than Source Generators. For everyone else look at areas that you currently fall back on runtime reflection and consider replacing it with a Source Generator. \n\nFor now though, it appears that the next release of the Prism Magician will have to include some shims to take the reworked generators and make them work with the Uno Source Generators.","date_published":"2020-12-22T12:26:00.000Z","date_modified":"2020-12-13T21:26:04.000Z","tags":[".NET","Prism","Xamarin","source generators","Roslyn","Uno Platform"]},{"id":"https://dansiegel.net/post/2020/05/07/icon-fonts-made-easy","url":"https://dansiegel.net/post/2020/05/07/icon-fonts-made-easy","title":"Icon Fonts made Easy","summary":"Coming from a Pre-Xamarin background of web development, I have always loved fonts like Font Awesome. Naturally I was pretty excited that Xamarin.Forms finally...","content_text":"Coming from a Pre-Xamarin background of web development, I have always loved fonts like Font Awesome. Naturally I was pretty excited that Xamarin.Forms finally added a FontImageSource to make it easier to use Font based Icons, but it still frankly was a pain to use. \n\n## Why Out of Box Is Terrible\n\nOk this might sound a little harsh, but to be honest even the geekiest among us don't go around memorizing and quoting unicode characters, so if you want to be able to use your custom icons you almost certainly need to create some sort of Mapping class.\n\n```csharp\npublic static class FontAwesomeBrands\n{\n    public const string FontFamily = \"fa-brands-400.ttf\";\n\n    public const string TwitterSquare = \"\\uf081\";\n    public const string FacebookSquare = \"\\uf082\";\n    public const string Linkedin = \"\\uf08c\";\n}\n```\n\nNow this is a little better because at least now we have made it human readable for which icon we're using and which font we've used... but it's still pretty verbose...\n\n```xml\n<Label Text=\"{x:Static fonts:FontAwesomeBrands.TwitterSquare}\" />\n```\n\nOf course this probably also dismisses the fact that all we want to do is set the text to our icon here, but we also had to specify the FontFamily. While there are several common approaches here we'll just say it might look like this:\n\n```xml\n<Label Text=\"{x:Static fonts:FontAwesomeBrands.TwitterSquare}\"\n       FontFamily=\"{x:Static fonts:FontAwesomeBrands.FontFamily}\" />\n```\n\n## Hitting that Easy Button\n\nLuckily there's a new package in town that aims to help simplify this allowing you to cut down on the complexity. Built on top of the Embedded Fonts introduced in Xamarin.Forms 4.5, the AP.MobileToolkit.Forms.Fonts, not only has a long package name, but helps package and consume icon fonts. Currently in preview it ships with packages for Font Awesome Free. \n\n![Icon Fonts made Easy](/images/blog/icon-fonts-made-easy/01-image.webp)\n\nTo get started with Font Awesome all you need to do is install any of the Font Awesome packages and register the Font with the Font Registry in your Application.\n\n```csharp\npublic partial class App\n{\n    public App()\n    {\n        FontRegistry.RegisterFonts(\n            FontAwesomeRegular.Font,\n            FontAwesomeSolid.Font,\n        );\n    }\n}\n```\n\nWith that little bit of code your application is now ready to use either font. Now you just need to consume it. With the Icon XAML extension it really couldn't be easier. Naturally we'll want to figure out which icon we want to use, just as if we weren't using Xamarin.\n\n![Icon Fonts made Easy](/images/blog/icon-fonts-made-easy/02-image.webp)\n\nIf we do a quick search on the Font Awesome website we'll get something like this. Since we love how easy it is to use this we'll use the grin-hearts icon to reflect it. \n\n![Icon Fonts made Easy](/images/blog/icon-fonts-made-easy/03-image.webp)\n\nOf course when we look at our icon we can see the unicode, but that isn't overly helpful or readable... but if we look at the classes that are used on the web this helps us easily identify that it's the Grin-Hearts icon in Font Awesome Regular, so we'll use this with the Toolkit's Icon extension.\n\n```xml\n<ContentPage xmlns=\"http://xamarin.com/schemas/2014/forms\"\n             xmlns:x=\"http://schemas.microsoft.com/winfx/2009/xaml\"\n             xmlns:ap=\"http://avantipoint.com/mobiletoolkit\"\n             x:Class=\"DemoFonts.MainPage\">\n    <Label Text=\"{ap:Icon 'far fa-grin-hearts'}\" />\n</ContentPage>\n```\n\nOk now I know some of you may be thinking this looks great except this is still a magic string. Well the AP.MobileToolkit has you covered there as well so you could alternatively do:\n\n```xml\n<ContentPage xmlns=\"http://xamarin.com/schemas/2014/forms\"\n             xmlns:x=\"http://schemas.microsoft.com/winfx/2009/xaml\"\n             xmlns:ap=\"http://avantipoint.com/mobiletoolkit\"\n             x:Class=\"DemoFonts.MainPage\">\n    <Label Text=\"{ap:Icon {x:Static ap:FontAwesomeRegular.GrinHearts}}\" />\n</ContentPage>\n```\n\n![Icon Fonts made Easy](/images/blog/icon-fonts-made-easy/04-image.webp)\n\nJust like that we have a working custom font, installed via NuGet. It took a very simple line of code to setup in our App and then we were free to easily use it throughout our app.\n\n## Next Steps\n\n-   Install it from NuGet.org\n-   Be sure to [give it a Star on GitHub](https://github.com/AvantiPoint/AP.MobileToolkit.Fonts \"give it a Star on GitHub\")","date_published":"2020-05-07T01:00:00.000Z","date_modified":"2020-05-07T08:22:29.000Z","tags":["Xamarin","Xamarin Forms","XAML","font awesome","icons","embedded fonts"]},{"id":"https://dansiegel.net/post/2019/08/07/androidx-app-bundle-and-profiled-aot-for-xamarin-android","url":"https://dansiegel.net/post/2019/08/07/androidx-app-bundle-and-profiled-aot-for-xamarin-android","title":"AndroidX, App Bundle and Profiled AOT for Xamarin Android","summary":"Recently I tweeted about some early observations on some updates I made for an Android project that's currently in the App Store. What was so amazing about this...","content_text":"Recently I tweeted about some early observations on some updates I made for an Android project that's currently in the App Store. What was so amazing about this is that the App Bundle was showing a download size that was roughly around 18% of what the traditional APK per ABI would produce.\n\n> On the top is a traditional Android app deployment with an APK per ABI. On the bottom is the same app updated using [#xamarinforms](https://twitter.com/hashtag/xamarinforms?src=hash&ref_src=twsrc%5Etfw) 4.1, [#prismlib](https://twitter.com/hashtag/prismlib?src=hash&ref_src=twsrc%5Etfw) 7.2, the new AAB, Profiled AOT, and migrated to use AndroidX… there is hardly any difference in download size... 🤣 [pic.twitter.com/FcII7SGXGG](https://t.co/FcII7SGXGG)\n> \n> - Dan Siegel (@DanJSiegel) [August 5, 2019](https://twitter.com/DanJSiegel/status/1158419581913841670?ref_src=twsrc%5Etfw)\n\nThe truth is some of these numbers are a little misleading. For instance while Google shows a download size around 4.3 - 4.8MB, in practice I really am seeing around a 7MB download from Google Play. While it is about 50-60% larger than what I see the download should be from the Release Dashboard in Google Play, it's still only around 29% of the size of the existing stable release that customers are downloading right now. In some respects with Unlimited data being widely available in major markets like the US, and very large internal storage being available on most devices it's still very attractive to ship smaller app packages to customers. Surprisingly it's really not that difficult to update your project to use all of this, though the CI/CD gets a little trickier.\n\n## Android App Bundle\n\nI'm not going to go into detail about the Android App Bundle as I'm sure you can find plenty of other articles that will educate you more on what they are. For the purposes of this post I am simply going to define them as an optimization of a single APK that contains the necessary resources for all of your target ABI's. In the case of the app that I referenced in my Twitter post, the generated Android App Bundle was about 10MB which you may notice by itself was less than half the size of the existing APK size of the app in Google Play. So how do you update your Xamarin.Android project to start generating an .aab? Well for starters your build environment will need to be using Xamarin Android 9.4 or later. At the moment the hosted agents in Azure DevOps / App Center do not have that out of the box. \n\nIt really couldn't be easier to generate the .aab though as you simply need to add a single property to the csproj for your Xamarin.Android project.\n\n```xml\n<PropertyGroup>\n  <AndroidPackageFormat>aab</AndroidPackageFormat>\n</PropertyGroup>\n```\n\nNote that while this snippet shows the `AndroidPackageFormat` property being declared in a root PropertyGroup (without conditions), you could put this in a PropertyGroup that is conditioned for Release or Store builds if you still want to generate an APK for Debug or Release and then ship an .aab to Google Play. It's also important to note here that before you can upload an .aab to Google Play you must delegate signing to Google. If you have not previously done so you will need to export your keystore with the private key from Android Studio so that you can upload it to Google and enable Android App Bundles for your app.\n\n### Critical For Distribution\n\nIt is also worth noting here that as a gotcha when you version your builds the Version Name does not matter to Google. So if you're at version 2.0 and you release 2.1 even after rolling it out, it does not mean that your users will be able to download it. Google Play is very dependent on the Version Code. For those who have uploaded multiple APK's to Google Play you've probably given your build a Version Code like 98 only to see each APK show something like 200098, 300098, 400098, 500098 like shown in the picture I posted on Twitter. This becomes very important because if you notice the build of the Android App Bundle in that same picture shows the Version Code as 123. In order to download this update we had to offset our builds by 500000 so that the next build was 500124 which was therefore recognized as being a newer version than 500098 that was currently available for download.\n\n## AndroidX (Android JetPack)\n\nI'm not even going to pretend I fully understand everything around AndroidX. I do however like some of the promises that it's supposed to simplify the dreaded Android Support libraries. While the process I'm going to outline here is going to show you how to manually migrate to AndroidX I should add that there is hope on the horizon to make this a little easier.\n\n> We will be shipping a migration wizard type experience in 16.3 which will do all the dirty work for you  \n> \\- Jonathan Dick (via Xamarin.Android Gitter)\n\nBefore you start, if your project is still using packages.config to manage it's NuGet references be sure to use the migration wizard in Visual Studio to migrate to PacakgeReference. Projects using PackageReference will have a much easier time migrating as you only need to install the Top Level dependencies and not the entire dependency chain. To start open the NuGet Package Manager for your Xamarin.Android project. Be sure to enable preview packages and install the latest `Xamarin.AndroidX.Migration` package. Once you've installed that and rebuild you should start getting build errors. As you scroll through the various build errors that appear, you'll see each error lists a current Android Support package and the corresponding AndroidX counterpart. The important thing to consider here is that you may see some crazy number like 27 packages that need to be installed. This doesn't accurately represent what the top level packages are for your project. As an example here for the [Moment app update](https://github.com/AvantiPoint/Moments) we only had to install 3 AndroidX packages directly.\n\n-   Xamarin.AndroidX.Legacy.V4\n-   Xamarin.Google.Android.Material\n-   Xamarin.AndroidX.Browser\n\nIf you see the first two listed here chances are you should install them right away as they'll bring down your dependencies really quick. Don't be afraid to go to NuGet.org and look at the dependencies of each of the AndroidX packages you need to install. It will help you identify which ones you need to reference specifically and which you'll get transitively. \n\nYou can [read more](https://devblogs.microsoft.com/xamarin/androidx-for-xamarin/) on AndroidX from Jon Douglas on the official Xamarin blog.\n\n## Startup Tracing\n\nAOT tends to both solve and cause a lot of problems. One of the problems that many people do not realize that they are causing for themselves is app size bloat. While AOT will speedup performance on Android, it also is likely to double the size of your app. Startup Tracing or Profiled AOT is a newer thing from the Xamarin team promising to keep the app bloat from AOT down while optimizing the AOT around startup performance where people tend to be the most frustrated. I should probably start by saying before you use AOT or Profiled AOT, do not do this for a Debug build. Doing so may encourage behavior that is not overly productive from day drinking to banging your head on the desk asking where you went wrong in life. The answer of course was using AOT in a Debug build. \n\nTo use Profiled AOT (which is a great thing in a Release build) it really couldn't be easier. Similar to the Android App Bundle it simply requires a new property be added. The property should only be added to a Property Group intended for Release or the Store.\n\n```xml\n<PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' \">\n    <AndroidEnableProfiledAot>true</AndroidEnableProfiledAot>\n</PropertyGroup>\n```\n\nAgain you can [read more](https://devblogs.microsoft.com/xamarin/faster-startup-times-with-startup-tracing-on-android/) on Startup Tracing from Jon Douglas on the official Xamarin Blog.\n\n## Secret Sauce\n\nSince everyone thinks there is some secret sauce I'll say there's not exactly any secret sauce... you have what you need already. That is of course until you get to the topic of CI/CD. Right now basically every tool I might rely on is pretty far behind on supporting Android App bundles.\n\n### App Center\n\nAt the moment there isn't really anything you can do with App Bundles... in fact App Center has been pretty limiting for Android developers for a while with the fact they only supported a single artifact for distribution making it hard to generate a single APK per ABI... fast forward and they still don't have Android App Bundle support at all though the team says it should be available this month.\n\nWhile you probably could install Boots and generate the .aab the problem here is that App Center wouldn't be able to do anything with the artifact and you'd probably fail the build.\n\n### Azure Pipelines\n\nThe Xamarin.Android build task is utterly useless. I eventually gave up on it and just wrote a simple PowerShell script to generate my .aab. Luckily with Azure Pipelines you have full control over what you want to have available as an artifact so this made it really easy to grab the .aab later on so I could do something with it. What I ended up with was something like this in my Android build stage. This downloads my Keystore from Secure Storage, then does a NuGet restore (via MSBuild), builds and signs the Android app all in one single step. It's worth noting here that since Xamarin.Android already signs the generated package/bundle with a default keystore and Google Play requires the ability to use your keystore to sign the apks they generate from the App Bundle, you probably don't need the complexity of signing.\n\n```plain\n- task: vs-publisher-473885.motz-mobile-buildtasks.android-manifest-version.android-manifest-version@1\n  displayName: 'Bump Android Versions in AndroidManifest.xml'\n  inputs:\n    sourcePath: pathTo/AwesomeApp.Android/Properties/AndroidManifest.xml\n    versionName: '1.1.0'\n    versionCode: $(Build.BuildId)\n    versionCodeOffset: 500000\n\n- script: sudo $AGENT_HOMEDIRECTORY/scripts/select-xamarin-sdk.sh 5_18_1\n  displayName: 'Select Xamarin SDK version'\n\n- task: pjcollins.azp-utilities-boots.boots.Boots@1\n  displayName: Install Latest Android SDK\n  inputs:\n    uri: https://aka.ms/xamarin-android-commercial-d16-2-macos\n\n- task: DownloadSecureFile@1\n  name: androidKeyStore\n  inputs:\n    secureFile: $(KeystoreFileName)\n\n- powershell: |\n   if($env:SYSTEM_DEBUG -eq $true)\n   {\n     $extraArgs = '/bl:android.binlog'\n   }\n   $keystorePath = $env:KeystoreFilePath\n   $keystoreName = $env:KeystoreName\n   $keystorePassword = $env:KeystorePassword\n   $project = $env:AndroidProjectPath\n   $outputDirectory = \"$($env:BUILD_BINARIESDIRECTORY)/$($env:BuildConfiguration)\"\n   Write-Host \"Output Path = $outputDirectory\"\n   msbuild $project /t:SignAndroidPackage /p:Configuration=$($env:BuildConfiguration) /p:OutputPath=$outputDirectory /restore /p:AndroidKeyStore=true /p:AndroidSigningKeyStore=$keystorePath /p:AndroidSigningStorePass=$keystorePassword /p:AndroidSigningKeyAlias=$keystoreName /p:AndroidSigningKeyPass=$keystorePassword $extraArgs\n  displayName: Build & Generate AppBundle\n  env:\n    AndroidProjectPath: 'pathTo/AwesomeApp.Android.csproj'\n    Secret_AppCenterSecret: ${{ parameters.appcenterKey }}\n    KeystoreFilePath: $(androidKeyStore.secureFilePath)\n    KeystoreName: $(KeystoreName)\n    KeystorePassword: $(KeystorePassword)\n\n- task: PublishPipelineArtifact@0\n  displayName: 'Publish BinLog'\n  inputs:\n    targetPath: 'android.binlog'\n    artifactName: android-binlog\n  condition: and(failed(), eq(variables['system.debug'], true))\n\n- task: PublishPipelineArtifact@0\n  displayName: 'Publish Package Artifacts'\n  inputs:\n    targetPath: '$(Build.BinariesDirectory)'\n    artifactName: ${{ parameters.artifactName }}\n  condition: eq(variables['system.pullrequest.isfork'], false)\n```\n\nBuilds though are only the first part of it. This is where we kind of lose here. I'm sure if I spent some time I could write a script to handle this but for now manual uploads are where we're at. From Azure Pipelines there are two methods I tend to rely on to upload my artifacts to Google Play.\n\n-   App Center Distribution task: Well as we already discussed App Center doesn't support .aab so we're out of luck there at the moment.\n-   [Google Play task](https://marketplace.visualstudio.com/items?itemName=ms-vsclient.google-play): Since whoever at Microsoft is responsible for it doesn't seem to be responding to the community... I'm just not sure what to say on this front.\n\nThe important thing is that we do have a generated artifact though and with that we can at least manually upload the artifact to Google Play.","date_published":"2019-08-07T02:00:00.000Z","date_modified":"2019-08-07T11:24:33.000Z","tags":["Xamarin","AOT","Android","AAB","AndroidX","AppCenter","Azure DevOps","Google Play"]},{"id":"https://dansiegel.net/post/2019/08/05/getting-started-with-azure-pipelines-for-xamarin-developers","url":"https://dansiegel.net/post/2019/08/05/getting-started-with-azure-pipelines-for-xamarin-developers","title":"Getting Started with Azure Pipelines for Xamarin Developers","summary":"DevOps for Xamarin apps is a rather large topic. Rather than trying to go A-Z in one bite, I thought it might make more sense to divide this up into bite sized...","content_text":"DevOps for Xamarin apps is a rather large topic. Rather than trying to go A-Z in one bite, I thought it might make more sense to divide this up into bite sized chunks. In this first article we'll take a look at how to get started with Azure DevOps (aka Azure Pipelines... aka I've lost track of what we're supposed to call it anymore)… Obviously the first thing you'll need to do is to create a new Azure DevOps organization (assuming you don't already have one). If you don't you'll want to head over to https://dev.azure.com and create one. You should see a dialog similar to this.\n\n![Getting Started with Azure Pipelines for Xamarin Developers](/images/blog/getting-started-with-azure-pipelines-for-xamarin-developers/01-inline-b40ee4a2ab.webp)\n\nAfter creating your new organization you'll need to setup a project. This project could be whatever you need. For the purposes of this article we'll call it' the Xamarin Mobile project and make it private.\n\n![Getting Started with Azure Pipelines for Xamarin Developers](/images/blog/getting-started-with-azure-pipelines-for-xamarin-developers/02-inline-429b29dc89.webp)\n\nOnce you've created the project you should see something like this:\n\n![Getting Started with Azure Pipelines for Xamarin Developers](/images/blog/getting-started-with-azure-pipelines-for-xamarin-developers/03-inline-850b5181bc.webp)\n\nBut we're still not done yet. As you'll notice there's a repos section in here. We could choose to use the FREE private git hosting in Azure DevOps. But if our code lives somewhere else such as GitHub we can keep using Azure DevOps for our CI/CD pipelines. If that's the case you may want to head to the Project Settings. All of the Azure DevOps services will be on by default, however you can choose what you want to use to narrow it down and focus the view on only what you'll be using.\n\n![Getting Started with Azure Pipelines for Xamarin Developers](/images/blog/getting-started-with-azure-pipelines-for-xamarin-developers/04-inline-865aa826db.webp)\n\nRemember that we've just set up a brand new Azure DevOps organization so we only have what's available out of the box, and that's really not sufficient for Xamarin Developers.\n\n## Marketplace for Azure DevOps\n\nTo really light up Azure DevOps and make sure that we have the full power we need for our Xamarin CI Builds you'll want to head over to [https://marketplace.visualstudio.com](https://marketplace.visualstudio.com/) and make sure you're looking at the Azure DevOps tab. You may find a number of great extensions for \n\n![Getting Started with Azure Pipelines for Xamarin Developers](/images/blog/getting-started-with-azure-pipelines-for-xamarin-developers/05-inline-f7787950ad.webp)\n\nThe first two extensions you'll want to install I honestly cannot figure out why they are not included out of the box with Azure DevOps particularly since they're released by Microsoft.\n\n-   [Apple App Store](https://marketplace.visualstudio.com/items?itemName=ms-vsclient.app-store&targetId=fe365dbf-73e2-42dc-b8c4-fe29ab058e42&utm_source=vstsproduct&utm_medium=ExtHubManageList \"Apple App Store\"): As the name implies this will give us an ability to deploy directly to the App Store and makes it very easy to get builds into Test Flight\n-   [Google Play](https://marketplace.visualstudio.com/items?itemName=ms-vsclient.google-play&targetId=fe365dbf-73e2-42dc-b8c4-fe29ab058e42&utm_source=vstsproduct&utm_medium=ExtHubManageList \"Google Play\"): Again this extension will make it very easy to integrate and deploy directly to Google Play. We can deploy to an internal testers group, alpha, beta, or production as we see fit. NOTE: this extension does not currently support the new Android App Bundles (.aab)\n\nThe next two extensions are from our great friends on the on the Xamarin team but they are published individually and not by Microsoft as an organization.\n\n-   [Mobile App Tasks for iOS and Android](https://marketplace.visualstudio.com/items?itemName=vs-publisher-473885.motz-mobile-buildtasks&targetId=fe365dbf-73e2-42dc-b8c4-fe29ab058e42&utm_source=vstsproduct&utm_medium=ExtHubManageList \"Mobile App Tasks for iOS and Android\"): This great extension from James Montemagno makes it very easy to provide a unique version for each build of our app. This is particularly important for those times where we may need to upload version 1.5 of our app to the app store 10 times to get through QA, and then the app review. By ensuring we have a unique Build number on each build of version 1.5 we can continue to upload new artifacts for testers and eventual release.\n-   [Boots](https://marketplace.visualstudio.com/items?itemName=pjcollins.azp-utilities-boots&targetId=fe365dbf-73e2-42dc-b8c4-fe29ab058e42&utm_source=vstsproduct&utm_medium=ExtHubManageList \"Boots\"): Boots is an awesome .NET CLI Tool from Jonathan Peppers. Thanks to a little help from Peter Collins on the Xamarin team, it's been made even easier to use with this great extension. With this simple utility you can provide a download link for any Xamarin SDK such as an Alpha or nightly build of Mono, Xamarin.iOS or Xamarin.Android and it will download and install the SDK so that it's ready to use for your build.\n\nInstalling the Extensions\n\nIt really couldn't be easier to install the extensions. You can navigate directly to each extension in the marketplace by clicking on the links above. Then you will want to click the Get it free button. When you are getting ready to install the extension you'll see a screen like the one below. Be sure to take note of the organization as it may not have the organization selected for which you want to install to.\n\n![Getting Started with Azure Pipelines for Xamarin Developers](/images/blog/getting-started-with-azure-pipelines-for-xamarin-developers/06-inline-77938a926f.webp)\n\n## Secrets and Secure Files\n\nNow that we have the extensions set up, lets head back into Azure DevOps and click on the Pipelines, and then the Library. The Library will give us an easy to manage location for our resources.\n\n![Getting Started with Azure Pipelines for Xamarin Developers](/images/blog/getting-started-with-azure-pipelines-for-xamarin-developers/07-inline-eba0914033.webp)\n\nTo get started round up the Android keystore, and any provisioning profile and signing certificate you will need for your Android and iOS apps. Select the Secure Files tab and then start uploading your secure files. Note that there is a certain amount of insanity in this step as you just uploaded files that are currently unavailable to be used. You will need to open each file that you have just uploaded. You will see something like the following. Notice that the toggle switch for all of the pipelines to use this file is currently off, you will need to toggle it to the on position and then hit save.\n\n![Getting Started with Azure Pipelines for Xamarin Developers](/images/blog/getting-started-with-azure-pipelines-for-xamarin-developers/08-inline-783524d302.webp)\n\nNow we'll want to head back to the first tab we landed on and start adding some variable groups. How this looks for you may differ slightly based on your needs. In general though I tend to end up with 3 Variable Groups like the following:\n\n-   Android-Signing\n    -   AndroidKeystoreFileName\n    -   AndroidKeystorePassword\n    -   AndroidKeystoreAlias\n-   iOS-Signing\n    -   iOSDevelopmentCertificate\n    -   iOSDevelopmentPassword\n    -   iOSDevelopmentProvisioningProfile\n    -   iOSDistributionCertificate\n    -   iOSDistributionPassword\n    -   iOSDistributionProvisioningProfile\n-   MyAppSecrets\n    -   AppCenterKey\\_Android\\_QA\n    -   AppCenterKey\\_Android\\_Store\n    -   AppCenterKey\\_iOS\\_QA\n    -   AppCenterKey\\_iOS\\_Store\n\nAgain you will want to be sure that each variable group is allowing access to all pipelines otherwise the variables will not be available for the build you will setup next.\n\n### Variable Group Take Aways\n\n-   Android app signing is very different than for iOS. There is no need to track separate keystores for QA and Production.\n-   iOS App Signing is very dependent on how to intend to consume the app. If you plan on side loading the app outside the App Store/Test Flight you will need a Development certificate. If you're ok with doing QA through Test Flight it may be worth it to simplify and use a single production certificate. That said you should change variables used such as where analytics are tracked, backend etc so you should be careful not to release QA builds into the wild where a customer could potentially use it.\n-   You should have processes in place that ensure there is some manual validation that can occur before your app ends up on the Store.\n-   You should also separate where Analytics/Crash Diagnostics are going between Stage and Production. While App Center is rather horrible at this currently, creating separate apps in App Center to track different environments can be a helpful technique in easily identifying Development noise verses what your customers are really doing and experiencing.\n-   You are building the iOS and Android apps in more than one step. There is no reason to leak the Android app secret in the iOS build or lead the iOS app secret in the Android build... just provide the one you need at build.\n\n## Next Steps\n\nIn the next post we'll look at how we integrate all of this into a build using YAML and how we organize it.","date_published":"2019-08-05T04:06:00.000Z","date_modified":"2019-08-05T12:55:52.000Z","tags":["Xamarin","Azure DevOps","DevOps","iOS","Android"]},{"id":"https://dansiegel.net/post/2019/05/24/using-dependency-injection-everywhere","url":"https://dansiegel.net/post/2019/05/24/using-dependency-injection-everywhere","title":"Using Dependency Injection Everywhere","summary":"Recently I started putting together some extensions to make my life even easier with Dependency Injection. I really enjoy being able to use Prism's abstractions....","content_text":"Recently I started putting together some extensions to make my life even easier with Dependency Injection. I really enjoy being able to use Prism's abstractions. This means I can write code today without any regard for which actual container I may choose 6 months from now. If you've been following my [Twitch streams](https://twitch.tv/dansiegel) you may have seen me demo the Prism Container extensions. In talking with developers about them I realized it was about high time I wrote a blog post about what they are, and why you might want to use them.\n\n## Advanced Service Registrations\n\nFor 95%+ of your service registrations you're probably fine with registering a Service as a Transient (you get a new instance every time) or a Singleton (you get the same instance wherever you need it). \n\n```csharp\ncontainerRegistry.Register<IFoo, Foo>();\ncontainerRegistry.RegisterSingleton<IBar, Bar>();\n```\n\nThe truth though is that for real complex applications it isn't always that cut and dry. Sometimes you might want to have a single type that implements several services. While other times you might need to have some sort of Factory method to construct a new instance of your service, or still other times you may require some sort of Scoped Service. The Container Extensions provide a way that we can take these much more advanced concepts and utilize them as an addition to Prism without interfering with anything from the main Prism Library.\n\n```csharp\nprotected override void RegisterTypes(IContainerRegistry containerRegistry)\n{\n    // Registers IFoo & IBar\n    containerRegistry.RegisterMany<FooBar>();\n\n    containerRegistry.RegisterSingleton<IFooBuilder, FooBuilder>();\n    containerRegistry.RegisterDelegate<IFooBar>(BuildFooBar);\n}\n\nprivate static IFooBar BuildFooBar(IContainerProvider containerProvider)\n{\n    var foo = containerProvider.Resolve<IFooBuilder>();\n    return foo.Build(\"Some value\");\n}\n```\n\nYou may be wondering why not add this to Prism proper... who knows if there is enough support maybe it will be. But in the mean time this keeps the Prism codebase light weight with a more heavy duty API in a separate codebase.\n\n## Using it Outside of Prism\n\nSo one of the neat things about this is that the only real dependency with Prism is Prism.Core which has a few side effects such as making the Container implementation for DryIoc completely platform agnostic, and making it easy to use outside of Prism. The PrismContainerExtension has a few other benefits:\n\n-   It supports Splat\n-   It implements IServiceProvider\n-   It supports Microsoft.Dependency.Injection with an ability to create IServiceProvider from an IServiceCollection\n    -    There's an additional support package for Shiny to make this even easier\n-    PrismContainerExtension implements a Singleton pattern meaning you can initialize it in native code and continue to access the same container later from shared code\n\n## Prism Forms Extended\n\nDebugging can (though shouldn't) be hard. So how exactly does PrismApplication from the extended package make your life even easier? Well for starters we get global exception handling for:\n\n-   AppDomain\n-   TaskScheduler\n-   ObjCRuntime\n-   AndroidEnvironment\n\nThat's all pretty cool but that doesn't cover all of the errors we might encounter so we also get global handling for:\n\n-   Module Load Errors\n-   All Navigation Errors with the Navigation Uri, or the invoking method name (i.e. GoBackAsync, GoBackToRootAsync)\n\nNow for as awesome as all of that is, it still doesn't cover one insanely important area... XAML! So for all of those times you've ever had an issue where a Binding wasn't working and you're looking at the UI with no clue where to begin, you'll get logging for FREE from Xamarin Forms Binding errors and more.\n\n### Platform Specifics & Uri Navigation\n\nOk so Uri based navigation is nothing new in Prism, but perhaps one of the last problem children has been how do I use a Xamarin.Forms.TabbedPage dynamically from Prism **AND** set the title for when you need the TabbedPage in a NavigationPage. For those times you run into this situation and you want to simply pass title a title parameter to the TabbedPage you can now do that and have the Title bound. \n\nWhat's more is that the addition of IPageBehaviorFactoryOptions. With these options you have the ability to control several Platform Specifics globally.\n\n```csharp\ninternal class DefaultPageBehaviorFactoryOptions : IPageBehaviorFactoryOptions\n{\n    public bool UseBottomTabs => true;\n\n    public bool UseSafeArea => true;\n\n    public bool UseChildTitle => true;\n\n    public bool PreferLargeTitles => true;\n}\n```\n\n## Shiny\n\nI have to admit among my favorite new libraries of 2019 is [Shiny](https://github.com/shinyorg/shiny) from Allan Ritchie. It makes a lot of complex tasks stupidly simple and reliable. Interestingly about the time that Allan first told me about his new project coming into beta I had also just started to stabilize the Container Extensions. It was such a perfect fit that it took almost no work to integrate the two. For a traditional Prism Forms application this wouldn't be the case as you wouldn't easily be able to initialize your container, register what you need with the Microsoft.DependencyInjection.Extensions and then get that container ready to go inside of Prism Application. However because of the design of the Container Extension you can now simply base your ShinyStartup on the PrismStartup from the Shiny.Prism.DryIoc package and use the PrismApplication from the Prism.DryIoc.Forms.Extended package and you're done. It requires zero code changes to your existing Prism Application and your startup is simply:\n\n```csharp\npublic class MyStartup : PrismStartup\n{\n    public override void ConfigureServices(IServiceCollection services)\n    {\n        // Register services with Shiny like:\n        services.UseGps<MyDelegate>();\n    }\n}\n```\n\n## Next Steps\n\nBe sure to try out the Prism.DryIoc.Forms.Extended package for your Xamarin.Forms app or Prism.DryIoc.Extensions in your Prism.Wpf app. Be sure to [follow me](https://twitch.tv/dansiegel) on Twitch to see when I go live or have new videos available on more great Prism and Xamarin Forms development topics. If you try it out be sure to tweet at me [@DanJSiegel](https://twitter.com/DanJSiegel) and let me know how you like it or if there's something you'd like to see.","date_published":"2019-05-24T11:56:00.000Z","date_modified":"2019-08-15T08:10:46.000Z","tags":["Prism","Xamarin","Dependency Injection","Xamarin Forms"]},{"id":"https://dansiegel.net/post/2018/10/29/using-unsupported-di-containers-with-prism","url":"https://dansiegel.net/post/2018/10/29/using-unsupported-di-containers-with-prism","title":"Using \"Unsupported\" DI Containers with Prism","summary":"Developers around the world rely on Prism to build some pretty amazing apps. When I first saw Prism I was amazed at how quickly and easily I could develop an...","content_text":"Developers around the world rely on Prism to build some pretty amazing apps. When I first saw Prism I was amazed at how quickly and easily I could develop an application with complex needs, but with easy to follow, testable, and maintainable code. As is so often the case, developers tend to have very strong opinions. Which Dependency Injection Container to use is certainly no exception. To some extent developers choices come from what they have experience with.\n\nFor a variety of reasons the Prism team cannot support every container that developers may want to use. Prism 7 however made some major changes that make it easier than ever to use a container that isn't officially supported or shipped by the Prism team. Prism imposes very few requirements in order to use a container.\n\n1.  The container must support Transient and Singleton registrations\n2.  The container must support registering a specified instance\n3.  The container must support keyed registrations / resolving by name\n4.  The container must be mutable to support Prism Modularity\n\nIn the past when implementing support for your own container, you would still need a fair amount of knowledge of the container, and how Prism is supposed to work. Because of the container abstraction, this requirement has been reduced to only needing to understand the container you want to use.\n\nAmazingly you can introduce support for your container by overriding one additional method from PrismApplicationBase in either Prism.Forms or Prism.WPF, and implementing a single class that handles the mapping between Prism's container abstraction and the container you want to use.\n\nThere are some extremely [performant containers](https://github.com/danielpalme/IocPerformance) available such as Grace. As it turns out Grace is a fantastic example as it is virtually on par or slightly more performant than my favorite DryIoc. It's also a mature codebase with releases going back to 2013. It meets all of our \"Must Support\" items, and it's mutable so it even works with Prism Modularity. Unfortunately for Grace, over it's 5 year history, it has only accumulated around 76,000 downloads. Due to this low user adoption, no matter how performant it may be, it isn't a popular enough container to justify adding to Prism as a supported container.\n\n## Adding a Container Extension\n\nPrism 7's IOC Abstraction simply provides a mapping for the most common Registration and Resolution methods. In the case of the Grace DI Container we simply need to add this single class:\n\n```csharp\npublic class GraceContainerExtension : IContainerExtension<IInjectionScope>\n{\n    public GraceContainerExtension()\n        : this(new DependencyInjectionContainer())\n    {\n    }\n\n    public GraceContainerExtension(IInjectionScope injectionScope)\n    {\n        Instance = injectionScope;\n    }\n\n    public IInjectionScope Instance { get; }\n\n    public bool SupportsModules => true;\n\n    public void FinalizeExtension() { }\n\n    public void Register(Type from, Type to) =>\n        Instance.Configure(c => c.Export(to).As(from));\n\n    public void Register(Type from, Type to, string name) =>\n        Instance.Configure(c => c.Export(to).AsKeyed(from, name));\n\n    public void RegisterInstance(Type type, object instance) =>\n        Instance.Configure(c => c.ExportInstance(instance).As(type));\n\n    public void RegisterSingleton(Type from, Type to) =>\n        Instance.Configure(c => c.Export(to).As(from).Lifestyle.Singleton());\n\n    public object Resolve(Type type) =>\n        Instance.Locate(type);\n\n    public object Resolve(Type type, string name) =>\n        Instance.Locate(type, withKey: name);\n\n    public object ResolveViewModelForView(object view, Type viewModelType)\n    {\n        Page page = null;\n\n        switch(view)\n        {\n            case Page viewAsPage:\n                page = viewAsPage;\n                break;\n            case BindableObject bindable:\n                page = bindable.GetValue(ViewModelLocator.AutowirePartialViewProperty) as Page;\n                break;\n            default:\n                return Instance.Locate(viewModelType);\n        }\n\n        var navService = Instance.Locate<INavigationService>(withKey: PrismApplicationBase.NavigationServiceName);\n        ((IPageAware)navService).Page = page;\n        return Instance.Locate(viewModelType, new[] { navService });\n    }\n}\n```\n\nOnce we've added this single class we only need to add to update our App as follows:\n\n```csharp\npublic partial class App : PrismApplicationBase\n{\n    protected override IContainerExtension CreateContainerExtension() =>\n        new GraceContainerExtension();\n}\n```\n\nAs I mentioned, Prism's IOC abstraction only provides the most common functionality. This means that you could find an advanced scenario where you need direct access to the underlying container. To achieve a more complex registration, you can add an extension method like we provide in the Container specific packages:\n\n```csharp\npublic static class ContainerExtensions\n{\n    public static IInjectionScope GetContainer(this IContainerRegistry containerRegistry) =>\n        ((IContainerExtension<IInjectionScope>)containerRegistry).Instance;\n}\n```\n\nYou can find a full working [sample app on GitHub](https://github.com/dansiegel/PrismGraceDemo).","date_published":"2018-10-29T01:00:00.000Z","date_modified":"2018-10-28T23:35:50.000Z","tags":["Prism","Xamarin","Xamarin Forms","WPF"]},{"id":"https://dansiegel.net/post/2018/08/21/demystifying-the-sdk-project","url":"https://dansiegel.net/post/2018/08/21/demystifying-the-sdk-project","title":"Demystifying the SDK Project","summary":"I am often, and rightfully, accused of living on the bleeding edge. It can be quite painful being there as ideas are not always fully flushed out, and tooling is...","content_text":"I am often, and rightfully, accused of living on the bleeding edge. It can be quite painful being there as ideas are not always fully flushed out, and tooling is often just not there yet. When Microsoft began the push towards .NET Core and .NET Standard, I knew this was an area that I needed to be. It was clear to me that this was a major shift that was going to make .NET development more appealing to a variety of developers, and businesses. As I set out to learn this new paradigm I both struggled and enjoyed the massive project system simplification that was introduced in the xproj format with a json configuration. For a variety of reasons though at the 11th hour Microsoft completely changed directions going back to the csproj and ditching the whole concept of a json configuration altogether. For months I struggled to understand what was going on. \n\n## Why I struggled\n\nThere were a lot of reasons I struggled. The project system has a lot of loose but very important couplings with MSBuild. Frankly I had heard of msbuild, but I knew so little about it that I simply called it \"The Compiler\" (which is very inaccurate). Another reason that I struggled is that there isn't exactly a lot of documentation to explain how the project system works, or what elements mean. Then of course have you ever looked at the older style of csproj? There is a lot of nonsense xml going on there. You can kind of figure out some stuff. You can for instance figure out that any of your code files that need to be compiled needed a `Compile` tag to include it in the compilation, but what on earth is all of the other crazy stuff going on there?\n\n## Breaking Through\n\nThe new SDK Style projects really help make what's going on in the project system easier to understand and customize because it's not polluted by a lot of insanity. You don't need to add a bunch of duplicate settings for Debug vs Release since it's already assumed these build configurations exist and we have some standard assumptions about them, like Release builds need to be optimized, while Debug configurations need all of our debug symbols to be able to step into them. Then of course we make some standard assumptions like all of your code files should be compiled (known as File Globbing). What's left over is often a file that has a `PropertyGroup` with a single `TargetFramework`.\n\n### PropertyGroup vs ItemGroup\n\nWhile this can get a little crazy when we start looking at creating custom build targets, we'll keep this simple for now. A PropertyGroup, is exactly what it sounds like. It's an area where you can declare Properties (think variable declarations), that will be used in the build process. There are a number of built in Properties ([Well-Known & Common properties](https://msdn.microsoft.com/en-us/library/ms164309.aspx?f=255&MSPPError=-2147217396)) that really come from msbuild, these include things like specifying the Assembly Name, where the build output should go, and some specialty variables that can be used to get things like the path to the Project File, or the current directory. While these properties can help us there are a number of other properties that can come into play from all over, and we can frankly make up properties as we see fit (more on that later).\n\nOk so now we have an idea about the PropertyGroup so what about ItemGroup's? Well ItemGroup's are all about grouping Items we need to do SOMETHING with. I admit that probably doesn't clarify what I mean. So let's look at the Xamarin Essentials csproj. It's a good use case where the decision was made to turn off the default file globbing.\n\n```xml\n<ItemGroup Condition=\" $(TargetFramework.StartsWith('netstandard')) \">\n    <Compile Include=\"**\\*.netstandard.cs\" />\n    <Compile Include=\"**\\*.netstandard.*.cs\" />\n  </ItemGroup>\n  <ItemGroup Condition=\" $(TargetFramework.StartsWith('uap10.0')) \">\n    <PackageReference Include=\"Microsoft.NETCore.UniversalWindowsPlatform\" Version=\"6.1.5\" />\n    <SDKReference Include=\"WindowsMobile, Version=10.0.16299.0\">\n      <Name>Windows Mobile Extensions for the UWP</Name>\n    </SDKReference>\n    <Compile Include=\"**\\*.uwp.cs\" />\n    <Compile Include=\"**\\*.uwp.*.cs\" />\n  </ItemGroup>\n```\n\nThere is a lot going on in this snippet so let's break this up. First you'll notice some conditions on these ItemGroup's. You do not have to ever use a Condition, but you can also put a Condition on Any Element. As I mentioned before, the EnableDefaultCompileItems Property was set to false, meaning that when this project is built, it will not compile ANY of the code unless we do something to include code. What you see here is that they have adopted a practice in which each file contains a platform identifier. This then allows them to have a condition in which the TargetFramework is evaluated and determine which C# files should be included in the compilation. Often times you may see multiple ItemGroup's in a csproj, with each Group containing a single set of Items, for instance only Embedded items, or Compile items, Project References. You'll notice here though that the ItemGroup can contain any set of Items, as the UWP ItemGroup contains a PackageReference, an SDKReference for Windows Mobile, and adds the UWP C# code.\n\n## Multi-Targeting\n\nPerhaps one of my favorite features of the SDK Style Project is that it makes Multi-Targeting that much easier. As you may have noticed in the snippet above from the Xamarin Essentials csproj, they have a single Project that targets both UWP and netstandard. Honestly, Microsoft only get's partial credit here. The new Project system introduces the ability to specify `TargetFrameworks` rather than a single `TargetFramework` if we so choose. Unfortunately the team only thought about Full Framework Targets like net45 and netcore/netstandard targets, which is why I say they get partial credit. For the Xamarin Developer (or even the 3 UWP developers out there), this gets really frustrating. Luckily the community has Microsoft MVP/RD Oren Novotny, who developed a completely custom SDK that ships via NuGet which introduces support for all kinda of new targets including UWP, Xamarin iOS, Android, Mac, and even Tizen and WPF.\n\n```xml\n<Project Sdk=\"Microsoft.NET.Sdk\">\n    <!-- Standard SDK Sytle Project that doesn't support cool targets -->\n    <<TargetFramework>netstandard2.0</TargetFramework>\n</Project>\n```\n\nSo what do we have to do to start Multi-Targeting more fun targets as a Xamarin Developer? Well it's actually pretty simple, again thanks to Oren, the Microsoft team added support so that all we need to do is replace the value in the Sdk attrubute of the Project. To start with let's look how you might do this if you only care about a single Project. \n\n```xml\n<Project Sdk=\"MSBuild.Sdk.Extras/2.0.54\">\n    <!-- Single Multi-Targeting Project... You control the version here as part of the Sdk string -->\n    <TargetFrameworks>netstandard2.0;xamarin.ios;xamarin.android;uwp10.0.16299</TargetFrameworks>\n</Project>\n```\n\nSuddenly you have the ability to create a single project that targets all of the platforms you want. But what about those cases where you still need to break code up into multiple projects? Well again it's very simple. Simply add `MSBuild.Sdk.Extras` as the Sdk value and then drop in a file called global.json next to your solution. (NOTE: You'll notice that this is what I've done for Prism)\n\n```js\n{\n    \"msbuild-sdks\": {\n        \"MSBuild.Sdk.Extras\": \"2.0.54\"\n    }\n}\n```\n\nOf course you could ask why should you care about Multi-Targeting? Well have you ever noticed that you have to do some crazy thing like:\n\n```csharp\nglobal::SomeProject.Platform.CoolRenderer.Init();\n```\n\nSuddenly you're referencing a bunch of Init methods that look like this:\n\n```html\npublic static void Init()\n{\n    // The Linker Sucks\n}\n\npublic static void Init()\n{\n    // Watch the build is going to warn me about a variable I'm not actually using for anything....\n    var a = DateTime.Now;\n}\n```\n\nTo me this has always been code smell. Ultimately the real reason you're having to do this so often is to ensure that the Linker sees an actual reference in code that goes into the Platform specific binary. This was a problem with the old project system since we had to have a sharable project (PCL), and then platform projects each of which needed to be bundled into a single NuGet. By Multi-Targeting you've already made references into the assembly to keep it from being stripped out reducing the legwork you need to do, to tell the Linker to pay attention to something else.\n\n### Multi-Targeting Snafu\n\nMulti-Targeting is a fantastic tool. Unfortunately for those working on a Mac there is a little bit of legwork you need to do. Visual Studio Mac does not currently support Multi-Targeting projects. It really should, and is very overdue in my opinion. If you agree, I suggest pinging Jordan Matthiesen ([@JMatthiesen](https://twitter.com/JMatthiesen)) to let him know this needs to be a top priority for the team (and in the next alpha release)... I did say there is a little bit of legwork you need to do though, I never said it doesn't work. MSBuild LOVES Multi-Targeting so you can build these projects from the command line all day long. In fact, as one of the nice things that Mac developers get for FREE, both MSBuild and NuGet are added to your PATH when you installed Visual Studio Mac making building from the command line very easy. Generally for these Multi-Targeting projects I simply move my workflow into Visual Studio Code where I can easily write code and build from the integrated terminal.\n\nI should probably admit the pain doesn't entirely stop there. UWP is simply an unresolvable target. The solution? Earlier I mentioned Conditions can be applied to any element, which includes the TargetFramworks element. If you lookup the well known MSBuild variables there is an OS variable. Unfortunately it's a bit simplistic meaning you're not going to figure out if you're on a Mac or Ubuntu or Centos, or Windows 7 or Windows 10... but you can at least figure out one thing... are you on Windows or not. So what does that look like:\n\n```xml\n<Project Sdk=\"MSBuild.Sdk.Extras\">\n    <PropertyGroup>\n        <TargetFrameworks>netstandard1.0;netstandard2.0;Xamarin.iOS10;MonoAndroid71;MonoAndroid80;MonoAndroid81;MonoAndroid90;MonoAndroid10.0</TargetFrameworks>\n        <TargetFrameworks Condition=\" '$(OS)' == 'Windows_NT' \">$(TargetFramework);uap10.0.16299</TargetFrameworks>\n    </PropertyGroup>\n</Project>\n```\n\n## Packaging\n\nSome of you may be wondering why you should be packaging your code? I've talked with a number of developers over the years who are engaged in a process in which for each release the entire code base is pulled from source control and built and released in one go. I've heard some interesting arguments for the practice, though I completely disagree with them. To be clear obviously something has to be built, but all of your common support libraries should be built and packaged as they are updated. There are actually a few benefits to this:\n\n1.  This reduces build times... Imagine you have a single support library that's used in 5 applications that are released across your organization. This literally eliminates 4 completely unnecessary builds of that single project. Of course the reality is that you probably have a bunch of support libraries making the results that much greater.  \n    ![Demystifying the SDK Project](/images/blog/demystifying-the-sdk-project/01-image.webp)\n2.  Versioning... It is a little scary when you think about it, but so many companies NEVER version their code. I have literally seen projects that started 15 years ago that are still on version 1.0.0.0 (from the template). In my experience these are companies that are probably storing your passwords in clear text, prefer http over https, and think a 56k modem is high speed internet instead of a painful memory of the 1990's. If you aren't versioning your code you really have no idea when a problem was introduced, if a problem has been fixed, or a regression has been made... you only have guesses.\n3.  Garbage In -> Garbage Out... because you've built and shipped that project independent of the rest of your monolithic applications, it means that you have had a chance to validate the code base before it finds it's way into use by others in your development team or a production environment. For many (realistically) this means that you are protecting yourself from that developer who checked in code that doesn't build. For others it means that you have ensured that all of your unit tests for that project have both run and passed.\n4.  Testability... I know what you're thinking, you're perfect, and so are the rest of the developers on your team. I totally understand, that's why I like to wear the shirt declaring \"I don't always test my code, but when I do, I do it in Production\". But for that time when maybe you forgot to update that one repo that you aren't responsible for, but that repo is required to build the project you are responsible for. The simple truth is as a .NET developer you're used to looking at the package manager for Updates. When your support libraries are packaged and available to your team via a private or public NuGet feed, it becomes easy to discover that an update is available. Because the discoverability is actually going up, it means that the entire team really has a better opportunity to test the code in development before it ever sees production.\n\n### How do you get started?\n\nMaybe you didn't need convincing, maybe you just need to know how to get started. Well for starters, let's completely toss out the idea of using a nuspec. They're annoying and frankly if you're multi-targeting... they are error prone. There are still a few monolithic projects out there like Xamarin.Forms that still require the use of a nuspec (largely due to the issues around Packing that the NuGet team needs to fix/implement), but the reality is that if you're using a Sdk Style project you probably don't need it.\n\nEarlier I mentioned that you could completely make up properties to put in the PropertyGroup of your csproj. Well when the Sdk Style projects were created, the folks at Microsoft decided to make up some new Properties to help with the very common task of packaging your projects. Many of these properties can be found at the links below. Some are a little harder to discover such as the GeneratePackageOnBuild property. By default this is false, however when you set this to true, all you need to do is build your project and each build will generate a new NuGet package for any packable projects in your solution. You'll find there is no right or wrong way as much as there is a way that makes sense for the project you are working on. Many of my projects, including Prism include a Directory.build.props in the solution directory, this allows me to set this value in a single place. Since IsPackable is true by default this means that you need to have some logic to set IsPackable to false on projects that should not be packed such as Tests and Samples.\n\n### Project References... Package References Oh My\n\nYou may know a little bit about a Project Reference and Package Reference. The difference here being that a Package Reference comes in from a NuGet feed, while a Project Reference is a Reference to a local project in the file system. So what happens then when you want to build and package a project? What happens to those Project References? A friend of mine recently asked if I could come take a look at a project he had been working on. Well every Project Reference is assumed to be a Reference that will be needed by the generated package. This means that there is no need to have some crazy conditional includes for a Package configuration.\n\n```xml\n<Project Sdk=\"MSBuild.Sdk.Extras\">\n    <PropertyGroup>\n        <TargetFramework>netstandard2.0</TargetFramework>\n    </PropertyGroup>\n\n    <ItemGroup Condition=\" $(Configuration) != 'NuGetRelease' \">\n        <ProjectReference Include=\"../AnotherProject/AnotherProject.csproj\" />\n    </ItemGroup>\n\n    <ItemGroup Condition=\" $(Configuration) == 'NuGetRelease' \">\n        <PackageReference Include=\"AnotherProject\" Version=\"$(Version)\" />\n    </ItemGroup>\n</Project>\n```\n\nAll you actually need is just your ProjectReference. When the project is built, this assumes that it is being Packed and will actually pick up whatever the version number is that, that specific project was packed with.\n\n```xml\n<Project Sdk=\"MSBuild.Sdk.Extras\">\n    <PropertyGroup>\n        <TargetFramework>netstandard2.0</TargetFramework>\n    </PropertyGroup>\n    <ItemGroup>\n        <ProjectReference Include=\"../Foo/Foo.csproj\" />\n    </ItemGroup>\n</Project>\n```\n\nBecause it will pick up the other project automatically it means that you just need to ensure that the Pack target is invoked.\n\n```bash\n> dotnet pack MyProject.csproj -c Release\n> msbuild MyProject.csproj /p:Configuration=Release /t:pack\n```\n\nEarlier I mentioned the GeneratePackageOnBuild element which is false by default. All we need to do is set this to true like in the following example or add it to our Directory.build.props file and EVERY build will now generate a package automatically.\n\n```xml\n<Project Sdk=\"MSBuild.Sdk.Extras\">\n    <PropertyGroup>\n        <TargetFramework>netstandard2.0</TargetFramework>\n        <GeneratePackageOnBuild>true</GeneratePackageOnBuild>\n    </PropertyGroup>\n</Project>\n```\n\n## Directory.build.props\n\nFor those paying attention, you've heard me mention the Directory.build.props... this is one of my favorite files, and in some ways a replacement for the nuspec\\*, in other ways it's just something I use to make my DevOps processes smoother. This is a slightly refined version of what I have published previously.\n\n```xml\n<Project>\n  <PropertyGroup>\n    <Product>$(AssemblyName) ($(TargetFramework))</Product>\n    <DefaultLanguage>en-US</DefaultLanguage>\n    <Authors>Your Name Here</Authors>\n    <Copyright>© $([System.DateTime]::Now.Year) Your Name Here</Copyright>\n    <PackageIconUrl>Uri to an icon image (png)</PackageIconUrl>\n    <PackageLicenseUrl>Uri to the license</PackageLicenseUrl>\n    <PackageProjectUrl>Uri to the project</PackageProjectUrl>\n    <RepositoryUrl>Uri to clone the project</RepositoryUrl>\n    <PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>\n    <RepositoryType>git</RepositoryType>\n    <!-- Root control Version Prefix -->\n    <VersionPrefix>1.0.0</VersionPrefix>\n  </PropertyGroup>\n\n  <!-- CI Helpers -->\n  <PropertyGroup>\n    <PackageOutputPath>$(MSBuildThisFileDirectory)/Artifacts</PackageOutputPath>\n    <PackageOutputPath Condition=\" $(BUILD_ARTIFACTSTAGINGDIRECTORY) != '' \">$(BUILD_ARTIFACTSTAGINGDIRECTORY)</PackageOutputPath>\n    <IsPackable Condition=\" $(ProjectName.Contains('Sample')) \">false</IsPackable>\n    <IsPackable Condition=\" $(ProjectName.Contains('Test')) \">false</IsPackable>\n    <GeneratePackageOnBuild>$(IsPackable)</GeneratePackageOnBuild>\n    <IS_PREVIEW Condition=\" $(IS_PREVIEW) == '' \">false</IS_PREVIEW>\n    <IS_RELEASE Condition=\" $(IS_RELEASE) == '' \">false</IS_RELEASE>\n    <VersionPrefix Condition=\" $(BUILD_BUILDNUMBER) != '' \">$(VersionPrefix).$(BUILD_BUILDNUMBER)</VersionPrefix>\n    <VersionSuffix>ci</VersionSuffix>\n    <VersionSuffix Condition=\" $(IS_PREVIEW) \">pre</VersionSuffix>\n    <VersionSuffix Condition=\" $(IS_RELEASE) \"></VersionSuffix>\n  </PropertyGroup>\n</Project>\n```\n\nYou'll notice that in this Directory.build.props file I have split it into two PropertyGroups to make it a little easier to read. So let's take a look at the first PropertyGroup.\n\n-   Product: The Product line here gets updated to include both the Target Framework and Assembly Name instead of just the Assembly Name. This is particularly helpful for multi-targeting projects as it can help identify which framework specifically was being used when an error occurred.\n-   You'll notice several elements here that contain placeholders for Uri's for specific to your project, and your name. These are all elements that came from the nuspec which are now taken care of and will be uniform across your entire solution helping to ensure that you don't have to duplicate values all over. \n-   VersionPrefix: This is the root version number that I want to control. Every single build will start with this version string.\n\nOk great, now let's take a little closer look at what's going on in the CI Group.\n\n-   PackageOutputPath: Maybe you have just one project, or maybe you have 10 that are built and packaged for your solution. Even with one, it can get a little tedious to have to drill down into the Project's output folder {Path To Project}/bin/{Build Configuration} each time you want to get the generated NuGet. When you have multiple projects though this gets really annoying. By setting this value we ensure that all of the packages are created in a common location making it easier to find. By default we are creating an Artifacts folder under the current directory (where the Directory.build.props is located). On VSTS however we are defaulting that location to be in the Artifact Staging Directory defined by VSTS.\n-   IsPackable: By default this is true, so we have a check to see if the Project Name contains either the word Test or Sample. If it contains either one we mark the project as NOT packable.\n-   GeneratePackageOnBuild: By default this is false meaning you either need to explicitly invoke the Pack target. By setting this to true we will generate the Packages on each build. If this is too much, or you don't want to accidentally ship a Debug build, you could add a condition to only set it to true when the build Configuration is Release.\n\n\\*NOTE:  \nJust to prevent some confusion here, there is still a nuspec in the process, only it is automatically generated by the build task rather than you having to maintain it as part of your project.\n\n### Helpful Links\n\n-   [Additions to the csproj format for .NET Core](https://docs.microsoft.com/en-us/dotnet/core/tools/csproj)\n-   [NuGet pack and restore as MSBuild targets](https://docs.microsoft.com/en-us/nuget/reference/msbuild-targets)\n\nFor more information and to see how I build many of my tools and support libraries see this post I wrote on [the new Project Format](/post/2018/03/29/net-standard-and-the-new-project-format-for-xamarin-developers). Still have questions feel free to leave a comment or reach out on Twitter.","date_published":"2018-08-21T01:00:00.000Z","date_modified":"2020-03-09T07:35:46.000Z","tags":[".NET","Xamarin","SDK Projects"]},{"id":"https://dansiegel.net/post/2018/07/18/azure-active-directory-b2c-for-xamarin-applications","url":"https://dansiegel.net/post/2018/07/18/azure-active-directory-b2c-for-xamarin-applications","title":"Azure Active Directory B2C for Xamarin Applications","summary":"You may have heard about Azure Active Directory B2C before. There have been a number of posts on the topic previously, including an episode with Matthew Soucoup...","content_text":"You may have heard about Azure Active Directory B2C before. There have been a number of posts on the topic previously, including an episode with Matthew Soucoup on the [Xamarin Show](https://channel9.msdn.com/Shows/XamarinShow/Azure-Active-Directory-B2C-Authentication-For-Mobile-with-Matthew-Soucoup). So why yet another blog post? Well to be honest the documentation can be a little confusing, and there is more to the setup of a tenant than you may have read about. There is absolutely nothing difficult about it in any way. However if you miss some critical configuration steps you'll struggle to ever authenticate with Azure Active Directory.\n\n## Why Azure Active Directory B2C\n\nWell for starters most of our apps today need some sort of authentication. There is a huge liability with storing user credentials, so while you might be able to use an OSS solution to implement your own OAuth flow, you're now taking the direct responsibility for properly maintaining the security of your users. If you're a large Enterprise that may not be a huge problem for you. For the rest of us (and even those large Enterprises), there is is a lot of benefit in offloading these tasks to 3rd parties like Microsoft. Not to mention that with the B2C offering we can further push off the responsibility to a number of common OAuth providers like Facebook, Twitter, LinkedIn, Google, etc.... and by checking a box you can enable 2-Factor authentication.\n\nUltimately what this means is that remove identifying user information from your own database storing only the Active Directory ObjectId for the user in your own database making breaches inherently less damaging as there is nothing more than a Guid in your database.\n\nBeyond the security topic, cost is also important, particularly to a small business. While some of my larger clients have had projected user bases that may be in the hundreds of thousands or millions, for the vast majority of my clients Azure Active Directory B2C represents an Enterprise Grade OAuth service that will cost them absolutely NOTHING as their realistic projected user base ranges from a couple of users to less than 5,000. Since Azure Active Directory B2C gives you 50,000 users and 50,000 authentications per month for free, this results in the service being 100% free for them to use.\n\n## Basic Concepts\n\nIt is important to remember the Azure Active Directory B2C is built on top of Azure Active Directory. This means that you do not have some magical new offering from Microsoft, but an existing, trusted, enterprise grade offering with some extensions that make a Business offering suitable to use directly with your Customers. This also means that IAM for your staff is handled through standard Active Directory user groups. \n\nAzure Active Directory / B2C both follow some basic OAuth concepts. Among these concepts is that you may have 1 - \\* Client Applications that are authenticating with the service. It can be a little confusing and this is probably where you're likely to go wrong in the configuration (more on that in a minute).\n\nWorking with Azure Active Directory B2C might be a little confusing for Xamarin developers who are looking for that Native approach. Since we are working with an OAuth service we are forced to use a web view to actually authenticate. This means you cannot create that fully native view that makes a rest call as the user will have to Register or Login using the web view from the MSAL library. \n\n## Configuring the Application in Azure\n\nWhen you first open your B2C tenant you should see something like the following (be sure to grab the tenant name circled as you will need it later for your Xamarin app):\n\n![Azure Active Directory B2C for Xamarin Applications](/images/blog/azure-active-directory-b2c-for-xamarin-applications/01-image.webp)\n\nYou'll need to begin by setting up an application. While there is no specific requirement that you set up more than one, my personal preference is to secure each application with it's own Application Id and limit what it has access to. For the purposes of this post I'll be setting up two applications, one for the Web API, and one for the Mobile App. It's worth noting here that this configuration is going to be a lot of back and forth as we set things up.\n\n![Azure Active Directory B2C for Xamarin Applications](/images/blog/azure-active-directory-b2c-for-xamarin-applications/02-image.webp)\n\nWe'll begin by adding a new Web API  application. To start we'll give this the name Awesome API, because let's face it... it's awesome. Then be sure to add a Reply URL. For now we'll add a localhost, this can be updated later. Next be sure to completely ignore the horribly wrong `optional` comment for the App ID... it's not... For this we'll give it the ID **api**.\n\n![Azure Active Directory B2C for Xamarin Applications](/images/blog/azure-active-directory-b2c-for-xamarin-applications/03-image.webp)\n\nNow let's add an application for our Mobile App. Since this is for our mobile app, we just want the Native Client.....\n\n![Azure Active Directory B2C for Xamarin Applications](/images/blog/azure-active-directory-b2c-for-xamarin-applications/04-image.webp)\n\nOk, I lied... so this is one of the things that isn't very obvious, but in order to be able to add scopes (which we'll need in our app), we actually have to enable the Web App / Web API section. Remember I said earlier to ignore the complete lie that App ID is optional. If we don't set the App Id we won't be able to add a scope, and we can't actually do that unless Web App / Web API is enabled.\n\n**IMPORTANT:** After you've created the application for the Mobile app, be sure to open it back up, copy the Application Id, and set the Custom Redirect URI, under the Native Client. The Redirect URI will always be:\n\n**msal{Your Application Id}://auth**\n\n![Azure Active Directory B2C for Xamarin Applications](/images/blog/azure-active-directory-b2c-for-xamarin-applications/05-image.webp)\n\nNow both of our applications have a basic configuration, we can go into the applications and set up the scopes. You'll see by default we have the user\\_impersonation scope. This is apparently used for the Microsoft Graph, and we'll want to set up our own scope. I personally haven't seen any documentation on right or wrong scopes, but as I understand it we actually will want to at least add a read scope here for our applications.\n\n![Azure Active Directory B2C for Xamarin Applications](/images/blog/azure-active-directory-b2c-for-xamarin-applications/06-image.webp)\n\nWith our scopes set in both applications, we can now take a look at the API Access, and here is one of those areas where again things aren't really obvious.\n\n![Azure Active Directory B2C for Xamarin Applications](/images/blog/azure-active-directory-b2c-for-xamarin-applications/07-image.webp)\n\nYou might be thinking as I did, that your application has permission to talk to itself... because why wouldn't it, right? Well it actually doesn't unless you add permission for each application to have access to itself under API Access. What happens if you skip this step? Well for starters you won't get an Access Token, and then what is the point of using Azure Active Directory B2C because you went through a bunch of setup to not have a token...\n\n![Azure Active Directory B2C for Xamarin Applications](/images/blog/azure-active-directory-b2c-for-xamarin-applications/08-image.webp)\n\nFinally for the Mobile App, be sure to add both the Mobile App itself with all permitted scopes, and the Web Api with all permitted scopes. When you're done, it should look something like this.\n\n![Azure Active Directory B2C for Xamarin Applications](/images/blog/azure-active-directory-b2c-for-xamarin-applications/09-image.webp)\n\n## Adding a Policy\n\nEarlier I mentioned that you will be using a Web View from the MSAL library to work with your B2C tenant. The way that this is exposed is with Policies. At the time of this article there are currently 6 policies that you can configure. These are fairly straight forward. To start, you'll likely want to add a policy to allow users to either Sign Up or Sign In. You can alternatively separate these tasks so that in your underlying UI you have separate Login and Register buttons with each one bringing you to a UI from B2C that makes sense for that work flow. If you have configured any Identity Providers (not covered by this article), you will be able to choose whether to use those and/or the local account. \n\n## Setting up the Xamarin App\n\nTo use Azure Active Directory or Azure Active Directory B2C in your Xamarin or Xamarin Forms application you will need to install the [Microsoft.Identity.Client](https://www.nuget.org/packages/Microsoft.Identity.Client/) (which is still only available as a preview package on NuGet). There is actually fairly decent setup instructions for considerations you'll want to have setting up the client in your Xamarin iOS and Android applications in the official sample app on [GitHub](https://github.com/Azure-Samples/active-directory-b2c-xamarin-native). While I would hardly consider the sample anywhere close to demonstrating best practices as it fully exposes the Tenant and Application Id in source control, not to mention I am very much against static references, I will say it is a great sample to validating that you have correctly configured your new B2C Tenant. \n\nGoing back into the Azure portal grab the Application Id for the Mobile App, along with the tenant name from the first step. Finally grab the read scope from the mobile app. If you're using the Azure sample app, you just need to update these couple of fields and run the app. If you put a break point in the MainPage.xaml.cs after the call to `AcquireTokenAsync` you should be able to evaluate the AuthenticationResult and see both an IdentityToken and AccessToken along with the expiration. If you see both, your tenant is correctly configured and you can now use Azure Active Directory B2C to correctly authenticate.","date_published":"2018-07-18T04:53:00.000Z","date_modified":"2018-07-18T15:33:40.000Z","tags":["Xamarin","Azure Active Directory B2C"]},{"id":"https://dansiegel.net/post/2018/06/20/developer-toolkit-for-visual-studio-mac","url":"https://dansiegel.net/post/2018/06/20/developer-toolkit-for-visual-studio-mac","title":"Developer Toolkit for Visual Studio Mac","summary":"Several years ago when I was still just a web developer wanting to break into mobile development, I asked myself how does anybody do this? You have to learn Java...","content_text":"Several years ago when I was still just a web developer wanting to break into mobile development, I asked myself how does anybody do this? You have to learn Java for Android, Objective-C or Swift for iOS.... of course then I learned about Xamarin. Without a doubt Xamarin makes the tedious tasks of mobile app development far easier by centralizing your code in one common language, and even further with Xamarin Forms by abstracting the UI into reusable code. That doesn't mean that creating a new app is by any means easy. In fact setting up a new app can take a lot of time.\n\nNearly a year and a half ago I introduced the Prism QuickStart Templates which were the first .NET Standard templates using the new project format available for Xamarin apps. The project took on a life of it's own and was loved by many even despite it's limited availability in the CLI. As I set out to bring the templates into Visual Studio for Mac, it again took on a life of its own. A number of developers and MVP's were gracious enough to give me their feedback on things they would like to see, and while it may have delayed my ability to release, what we have today is simply stunning.\n\n### Prism Template Studio and Developer Toolkit\n\nOk I admit it, it's a mouthful, and if you have a better name feel free to tweet it to [@DanJSiegel](https://twitter.com/DanJSiegel). Why the mouthful, because it is absolutely jammed pack with so many tools, so many helpers, and so many templates, that every time I explain it someone asks, \"well what about...\", and I keep either responding yeah it does that too... or yeah we could add that. It's probably that second one that has admittedly  generated the most delay in getting this out. Whether you use vanilla Xamarin Forms or Prism you'll want to install the Prism Template Studio and Developer Toolkit. \n\n### Templates\n\nAs the name suggests it contains the a Template Pack. This Template Pack isn't quite like anything you've seen before. There are 14 new project templates that ship in this Template Pack, including 7 projects for Unit and UI Testing, 3 more for building Prism Modules, and another 3 for Prism Applications, plus a new basic Xamarin Forms project template.\n\nEach of the templates bring something special for different developers. You can still go with the traditional flat \"Official\" template, or one includes PropertyChanged.Fody with projects and tests separated into src and tests folders. You can also take advantage of the powerhouse QuickStart Template or the App Center Connected App. Both of these provide the to setup a project in VSTS and automatically configure a Build in App Center.\n\n<iframe src=\"https://www.youtube.com/embed/An3eiue4KIw\" width=\"560\" height=\"315\" frameborder=\"0\" allowfullscreen=\"allowfullscreen\"></iframe>\n\n### Tools\n\nTo start there is some integrated tooling for all of your Xamarin projects to enable support for the Mobile.BuildTools, you can connect an existing project to an app in App Center, and even get some quick links to the Prism Docs, GitHub issues, and StackOverflow. Over time you can expect to see additional tooling for App Center, and refinements to do more with VSTS and better expand on your ability to get started with Unit and UI Tests.\n\nGet started today by making sure Visual Studio Mac is up to date, and then simply install the Prism Template Studio and Developer Toolkit from the Extension Manager.","date_published":"2018-06-20T23:22:00.000Z","date_modified":"2018-07-02T15:58:12.000Z","tags":["Prism","Xamarin","Xamarin Forms","templates","AppCenter","VSTS","DevOps","MobileToolkit"]},{"id":"https://dansiegel.net/post/2018/06/15/prism-7-1-preview-3","url":"https://dansiegel.net/post/2018/06/15/prism-7-1-preview-3","title":"Prism 7.1 Preview 3","summary":"Today we released the 3rd Preview for Prism 7.1. This is a very significant release for us and contains some very exciting changes. Forms Dependency Resolver At...","content_text":"Today we released the 3rd Preview for Prism 7.1. This is a very significant release for us and contains some very exciting changes.\n\n### Forms Dependency Resolver\n\nAt Build we released a special preview for Xamarin Forms. In that preview we released the much awaited ability to use your Application's DI Container to resolve types inside of Xamarin Forms such as your Renderers or Platform Effects. It was a great feature but there were some issues caused on Android by the transition from a default constructor to one that requires the Android Context. Preview 3 fixes this by adding a specific Android target to each of the DI packages to handle passing the Context to the Container while resolving your Renderers.\n\nWe asked the community and while people were very torn on the subject, it was very overwhelming that using the DependencyResolver is something that should be configurable. As a result we've updated PrismApplication's constructor to accommodate this. First we removed the optional parameter for IPlatformInitializer and simply provided both a Default constructor and one that takes IPlatformInitializer. Second we added a new constructor that takes both IPlatformInitializer and a boolean to control whether we should set the DependencyResolver. As you may have guessed both of backwards compatible constructors call the new constructor, and by default will pass `false` to prevent PrismApplication from setting the DependencyResolver. \n\nJust as with Preview 2, you can still override `SetDependencyResolver` in order to provide your own logic.\n\n#### Known Issues\n\nFFImageLoading is a very popular image handling library. Unfortunately the CachedImageRenderer as 2 completely unnecessary constructors as they will never be used by Xamarin Forms and they only serve to confuse a DI Container. By default most DI containers will attempt to resolve a type based on the constructor with the most arguments. In the event that more than one constructor exists with the same \"Highest\" argument count, it will select the first one. This is the case in the CachedImageRenderer which results in the container attempting to resolve the Renderer with `CachedImageRenderer(IntPtr, JniHandleOwnership)`.\n\nIn order to handle this you will need to add a specific registration for the Renderer in your Android Initializer. This will look different based on which container you are using. If you're using DryIoc, you can easily add either of the following examples to fix the issue:\n\n```csharp\npublic class AndroidInitializer : IPlatformInitializer\n{\n    public void RegisterTypes(IContainerRegistry containerRegistry)\n    {\n        containerRegistry.GetContainer().Register<CachedImageRenderer>(made: Made.Of(() => new CachedImageRenderer(Arg.Of<Android.Content.Context>())));\n        // OR with Reflection\n        containerRegistry.GetContainer().Register<CachedImageRenderer>(made: Made.Of(typeof(CachedImageRenderer).GetConstructor(new[] { typeof(Android.Content.Context) })));\n    }\n}\n```\n\n### Modularity\n\nModularity has been on my personal hit list for a while now, and Preview 3 makes some major changes to help accomplish the final goal of aligning the Modularity API between WPF and Xamarin.Forms as well as making it available for UWP. To start with we've moved the Modularity Exceptions from WPF to Prism.Core, along with ModuleInfo, IModuleInitializer, and IModuleManager. Among the changes, this means that Xamarin.Forms apps will be able to listen for the ModuleLoaded event and capture any exceptions that may occur during the Module's Initialization. \n\nFor WPF developers defining their ModuleCatalog in XAML this means a break as ModuleInfo is now in Prism.Core. Rest assured though that some care has been taken to ensure that any API changes are addative and beneficial. An example of this is that the constructor's from Prism.Form's version of ModuleInfo were added to ModuleInfo in Prism.Core. For Prism.Forms developer's a bigger break in ModuleInfo was introduced by changing ModuleType from `Type` to `string`. While I say bigger break, this should only affect developers who are directly referencing ModuleInfo's ModuleType property. Since the Modularity API in Prism.Forms favor's generics this should have a minimal impact for most developers.\n\n### XAML Navigation\n\nYep, I said it... This was an amazing idea and PR that came from the community. Over the past week I've had a chance to dogfood this one, and I have high hopes for what this will empower developers to do. Up until now you would need to have a ViewModel, inject the NavigationService, create a command, and an action for the command that uses the NavigationService to navigate to some other page, and then bind that command to some Button. Now with XAML Navigation you can simply have:\n\n```xml\n<Button Text=\"Continue\"\n              Command=\"{prism:NavigateTo ViewB}\" />\n```\n\nJust as an example this could be used to completely eliminate a ViewModel on a Page that is simply a landing page that simply prompts the user to continue. This could be very useful for pages used in OnBoarding new users where you are explaining how to do something in your app. There is full documentation on this feature in the [Prism Docs](https://prismlibrary.github.io/docs/). Be sure to read more there on how to use NavigationParameters which would again make it easier to handle scenarios where you are try to Navigate based on a Cell in a ListView or a RepeaterView that so many of us have implemented.\n\n### Additional Notes\n\nPerhaps one of the first things that developers have had to learn with Prism.Forms is that you must name INavigationService 'navigationService' in your constructor otherwise it won't be injected into your ViewModel. While that hasn't been the case in DryIoc for a while, this is now a thing of the past for Autofac and Unity as well. \n\nWhile you may not have heard of this one before, SourceLink is an amazing new tool for OSS libraries to empower developers debugging experience. Sadly this only works in Visual Studio on Windows and is only in the Backlog for Mac for now, but for those working in Visual Studio 2017 this will let you step into Prism's code while you debug. \n\nLast but certainly not least. A few months ago Oren Novotny began talking to me about signing NuGet packages. After hearing what he had to say, I had to agree wholeheartedly that it was something we should do for our user base. Beginning with Preview 3, we are now signing each NuGet package as part of our release pipeline. This means that when you consume our packages you will be able to verify that the package actually comes from the Prism team and has not been altered between us and you.\n\nBe sure to try out the new Prism 7.1 preview today and let us know what you think. Be sure there is more great stuff to come.","date_published":"2018-06-15T07:39:00.000Z","date_modified":"2018-06-15T18:40:53.000Z","tags":["Prism","Xamarin","Xamarin Forms","WPF","Modularity"]},{"id":"https://dansiegel.net/post/2018/04/02/prism-7-1-preview-1","url":"https://dansiegel.net/post/2018/04/02/prism-7-1-preview-1","title":"Prism 7.1 Preview 1","summary":"Maintaining a library can be exceptionally difficult. As time progresses new demands arise that weren't there when the API was first created. Sometimes simple...","content_text":"Maintaining a library can be exceptionally difficult. As time progresses new demands arise that weren't there when the API was first created. Sometimes simple work arounds can be found to prevent breaking library consumers when they upgrade. Sometimes the changes are no brainers that have no negative affects. Sometimes changes simply aren't made because the potential breaks are simply too risky. Other times the benefits simply outweigh the break and changes are made.\n\nPrism 7.1 is largely the result of changes that the Prism Team has come to realize had to be made. As part of the overall Prism 7.X effort, the team has been working on bringing the API closer together across each platform target where possible. Currently this is perhaps most evident with the introduction of the Prism.Ioc namespace allowing developers to more easily port from one DI Container to another, and even create Prism Modules that are sharable across projects with different DI Containers.\n\nIn this release have made some major changes to better unify the API between Xamarin Forms and our ongoing work with Jerry Nixon to bring Template 10 to Prism for UWP. This effort though represented the need to create a binary incompatibility, a need to create some breaking changes, and an opportunity to greatly improve the API for Xamarin Forms developers. So what are the changes? For starters we've migrated most of the Prism.Navigation namespace from Prism.Forms to Prism.Core. After a lot of deliberation we ultimately decided that these changes should not be available to WPF developers as it just doesn't make sense for WPF applications. \n\nIn addition to the binary incompatibility caused by moving the classes from one binary to another, this creates a secondary break in the WPF will NOT be supported for Xamarin Forms developers.\n\nI mentioned that there are breaking changes and some opportunities for improvements as well. The break that you will encounter should be fixable with a simple Find/Replace in your IDE or text editor, as NavigationParameters is now INavigationParameters which changes the method signatures for INavigatingAware, INavigatedAware, INavigationAware, IConfirmNavigation, IConfirmNavigationAsync, and INavigationService. While that may provide you with some unique opportunities for testing, that isn't the exciting change. The change is the return type from INavigationService from a simple Task to Task<INavigationResult>. Why is that so great? Well for one thing if the Navigation failed for some reason you'll have access to a Boolean to more easily execute that logic. It's also great though because until now the NavigationService could make it harder to determine what type of exception may have been thrown. INavigationResult fixes this by returning the actual exception that was thrown allowing you greater control over what to do with it.\n\n```csharp\nvar result = await _navigationService.NavigateAsync(\"BadPage\");\n\nif(!result.Success)\n{\n    await _pageDialogService.DisplayAlertAsync(result.Exception.GetType().Name, result.Exception.Message, \"Ok\");\n}\n```\n\nPerhaps my single favorite improvement in Prism 7.1 for Xamarin Forms developers is the inclusion of the ContainerProvider. This was born out of a desire to be able to declare types such as a TypeConverter that may rely on some service in your application. The ContainerProvider will allow you to declare in XAML, types that do not have a default constructor and inject any of your applications services into that type. \n\n```xml\n<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<ContentPage\n    xmlns=\"http://xamarin.com/schemas/2014/forms\"\n    xmlns:x=\"http://schemas.microsoft.com/winfx/2009/xaml\"\n    xmlns:prism=\"clr-namespace:Prism.Ioc;assembly=Prism.Forms\"\n    xmlns:converters=\"using:Prism.Forms.Tests.Mocks.Converters\"\n    Title=\"{Binding Title}\"\n    x:Class=\"Prism.DI.Forms.Tests.Mocks.Views.XamlViewMock\">\n    <ContentPage.Resources>\n        <ResourceDictionary>\n            <prism:ContainerProvider x:TypeArguments=\"converters:MockValueConverter\" x:Key=\"mockValueConverter\" />\n        </ResourceDictionary>\n    </ContentPage.Resources>\n    <Entry x:Name=\"testEntry\"\n           Text=\"{Binding Test,Converter={StaticResource mockValueConverter}}\" />\n</ContentPage>\n```\n\n### Unity\n\nUnity has been one of the most popular containers for Prism Developers. I have no doubt that this has a lot to do with the fact that it is the container Brian has used for years, has used in his demos and that was most widely available in the Prism Template Pack. The Unity team has made some major design changes in Unity 5.X. For Prism developers using Unity we have long since had a dependency on the Unity NuGet package. In it's current state, this actually broke Prism.Unity.Forms for netstandard1.0. \n\nThe Unity team has redefined the Unity NuGet package to be an all inclusive package that presents several problems. For Xamarin Forms developers, it introduces references to 6 more assemblies than what you actually need or would use. For WPF developers it creates a secondary, and hidden reference to CommonServiceLocator, as well as the inclusion of 5 more assemblies than what you need or Prism uses. To continue depending on this NuGet package represents an additional issue that it could continue to break Prism developers. To resolve this, Prism 7.1 has changed it's target from Unity to Unity.Container. This change will be unnoticeable to anyone who uses the new PackageReference to include NuGet's in their projects, particularly when you have your dependency on Prism.Unity or Prism.Unity.Forms and not Unity itself. For all other Unity developers, you should uninstall Unity from your projects before upgrading to Prism 7.1.","date_published":"2018-04-02T04:40:00.000Z","date_modified":"2018-04-02T12:40:19.000Z","tags":["Prism","Xamarin","Xamarin Forms","WPF"]},{"id":"https://dansiegel.net/post/2018/03/29/net-standard-and-the-new-project-format-for-xamarin-developers","url":"https://dansiegel.net/post/2018/03/29/net-standard-and-the-new-project-format-for-xamarin-developers","title":".NET Standard & the New Project Format for Xamarin Developers","summary":".NET Standard has really changed the ballgame for .NET Developers. In large part because the entire project system has experienced a revamp. Lately I've found...","content_text":".NET Standard has really changed the ballgame for .NET Developers. In large part because the entire project system has experienced a revamp. Lately I've found myself really encouraging developers to update their PCL libraries to .NET Standard 2.0. For developers who haven't made the jump it's easy to find yourself saying \"no we can't do it\". In reality it doesn't take as much effort as you think it does to update your projects. Why should you update your projects though? Well for starters PCL is painful, you lookup how to do something only to find out that it's not supported and sometimes there's no workaround. With .NET Standard the missing API's that lead to weird workarounds is a thing of the past.\n\n### Upgrading\n\nUpgrading really isn't as hard as you may think. For starters your csproj is going to start out about as simple as:\n\n```xml\n<Project Sdk=\"Microsoft.NET.Sdk\" ToolsVersion=\"15.0\">\n  <PropertyGroup>\n    <TargetFramework>netstandard2.0</TargetFramework>\n  </PropertyGroup>\n</Project>\n```\n\nThen of course we need to start adding in your dependencies. Now this is where it gets \"Hard\". It's hard because it means you need some familiarity with your project. You need to know what are the top level dependencies that your project has. For example if you're using Prism there are generally 3 Prism packages you're referencing, Prism.Core, Prism.Forms, and Prism.{Some Container}.Forms. It's only the last one that you actually need to reference in the new project format. You can of course add this from either Visual Studio or Visual Studio Mac or update it manually so that your project file now looks like:\n\n```xml\n<Project Sdk=\"Microsoft.NET.Sdk\" ToolsVersion=\"15.0\">\n  <PropertyGroup>\n    <TargetFramework>netstandard2.0</TargetFramework>\n  </PropertyGroup>\n  <ItemGroup>\n    <PackageReference Include=\"Prism.DryIoc.Forms\" Version=\"7.0.0.396\" />\n  </ItemGroup>\n</Project>\n```\n\nAssuming you wanted to get started with Prism for Xamarin Forms this would be all you would actually need as all three Prism packages are automatically brought in along with Xamarin Forms. Now let's say that you wanted to target a newer version of Xamarin Forms than 2.5.0.122203, such as the 3.0 preview that's now available. You simply need to add a new PackageReference for that version of Xamarin Forms or install it in the IDE's Package Manager.\n\nThat may seem too easy, and it is. Of course you need to make some more changes. You'll need to find the packages.config or project.json and delete those files... If you have a standard `Properties/AssemblyInfo.cs` you'll need to go ahead and send that one to the trash as well. With that your project is upgraded, and you're wondering why you didn't do this sooner....\n\n### Multi Targeting\n\nAround 5 years ago I first started trying to Multi-Target. My earliest attempts were pretty bad with a csproj file for each framework I wanted to target, all part of the same solution, and it generally resulted in build errors due to file locks as I had no clue how the build system worked back then. Honestly I've never found much documentation that made it very easy, and while I eventually figured out I could do lots of MSBuild trickery to make it work, and then manually develop a nuspec to pack my library, it was always really painful. The new Project system gives us some real advantages for Mutli-Targeting that make it a real breeze.\n\nI suppose though I should start with why on earth should you multi-target... and when would you want to? If you're a Xamarin developer chances are you want to Multi-Target. Internally and for all of my clients I generally start off with a common library. This is something that is really helpful to give me extensions, and custom controls that I may want to use across all of my apps or components like a Prism Module. A lot of that code is truly portable and I could easily handle it with a simple netstandard2.0 class library. However sometimes I'm implementing Platform Effects and Renderers for my controls that instantly require that I have a native binary for my iOS and Android projects. This is where multi-targeting really becomes very powerful. By Multi-Targeting I maintain a single Project which generates a single binary, native to the platform I need to target. Now if we expand on the basic project structure we saw above and now update our csproj to look like the following we can target both .NET Standard 1.3 & 2.0, along with Android, iOS, Mac, and UWP. It's worth noting that the non .NET Standard targets are really getting a lot of help due to the MSBuild.Sdk.Extras package from [Oren Novotny](https://oren.codes/).  \n\n```xml\n<Project Sdk=\"MSBuild.Sdk.Extras/1.5.4\" ToolsVersion=\"15.0\">\n  <PropertyGroup>\n    <TargetFrameworks></TargetFrameworks>\n    <TargetFrameworks Condition=\" '$(OS)' == 'Windows_NT' \">netstandard1.3;netstandard2.0;Xamarin.iOS10;Xamarin.Mac2.0;MonoAndroid80;uap10.0.16299</TargetFrameworks>\n    <TargetFrameworks Condition=\" '$(OS)' != 'Windows_NT' \">netstandard1.3;netstandard2.0;Xamarin.iOS10;Xamarin.Mac2.0;MonoAndroid80</TargetFrameworks>\n  </PropertyGroup>\n  <ItemGroup>\n    <Compile Remove=\"**/Platform/**/*.cs\" />\n    <None Include=\"**/Platform/**/*.cs\" />\n  </ItemGroup>\n  <ItemGroup Condition=\" $(TargetFramework.StartsWith('MonoAndroid')) \">\n    <None Remove=\"**/Platform/Droid/**/*.cs\" />\n    <Compile Include=\"**/Platform/Droid/**/*.cs\" />\n  </ItemGroup>\n  <ItemGroup Condition=\" $(TargetFramework.StartsWith('Xamarin.iOS')) \">\n    <None Remove=\"**/Platform/iOS/**/*.cs\" />\n    <Compile Include=\"**/Platform/iOS/**/*.cs\" />\n  </ItemGroup>\n  <ItemGroup Condition=\" $(TargetFramework.StartsWith('Xamarin.Mac')) \">\n    <None Remove=\"**/Platform/macOS/**/*.cs\" />\n    <Compile Include=\"**/Platform/macOS/**/*.cs\" />\n  </ItemGroup>\n  <ItemGroup Condition=\" $(TargetFramework.StartsWith('uap10.0')) \">\n    <None Remove=\"**/Platform/UWP/**/*.cs\" />\n    <Compile Include=\"**/Platform/UWP/**/*.cs\" />\n  </ItemGroup>\n</Project>\n```\n\nSo what's going on here anyway? Well for starters we're establishing some conventions for our code. We are saying that anywhere in our project that we have a folder named **Platform** we are going to change the inclusion of those files from **Compile** to **None**. This means that the IDE will display our code while MSBuild will ignore our code. Then, we start conditionally adding code back in so that when MSBuild is compiling for iOS and it encounters code that has a path that includes **Platform/iOS**, that code will be added back in for compilation. \n\n### Generating a NuGet\n\nIf you're trying to generate a library that you can easily consume in your projects, or if you're trying to make it available for the community at large, these new SDK style projects are make generating a NuGet easier than ever. You just need to worry about what targets you want to compile for, and the NuGet largely takes care of itself with very little that we actually need to add. It's really just a few properties that we need to add to our project. Of course, if you take a look at any of my projects you'll notice a recurring theme, most of my NuGet configurations aren't even in the project file at all. Along the way I've come to realize the power of a file called Directory.build.props. This is a little bit of a magic file. If it exists anywhere from the solution folder to your project folder it will automatically be picked up by MSBuild. \n\n#### Looking at a real world example\n\nPrism has more than 15 NuGet packages that have to generated on every build. Honestly for WPF we still use the older style projects which is a painful process, but the rest of the projects all share a lot of common logic.\n\n-   If there is a project that isn't a test project we don't want it to Generate a NuGet. \n-   The package authors are always going to the members of the Prism Team.\n-   The source is always located on GitHub in the same repository.\n-   We always want to provide symbols packages.\n\nWithout using the Directory.build.props in our solution directory we would have to replicate this information in every single project file. \n\n#### Setting your project up for NuGet Packaging\n\nIf you want to pack your project all you really need to do is to add the following Directory.build.props to your project:\n\n```xml\n<Project>\n  <PropertyGroup>\n    <Product>$(AssemblyName) ($(TargetFramework))</Product>\n    <NeutralLanguage>en</NeutralLanguage>\n    <Authors>Your Name Here</Authors>\n    <VersionPrefix>1.0.0</VersionPrefix</VersionPrefix>\n    <VersionPrefix Condition=\" '$(BUILD_BUILDID)' != '' \">$(VersionPrefix).$(BUILD_BUILDID)</VersionPrefix>\n    <IS_PREVIEW Condition=\" '$(IS_PREVIEW)' == '' \">false</IS_PREVIEW>\n    <IS_RELEASE Condition=\" '$(IS_RELEASE)' == '' \">false</IS_RELEASE>\n    <VersionSuffix>ci</VersionSuffix>\n    <VersionSuffix Condition=\" $(IS_PREVIEW) \">pre</VersionSuffix>\n    <VersionSuffix Condition=\" $(IS_RELEASE) \"></VersionSuffix>\n    <PackageProjectUrl>https://github.com/USER/PROJECT_NAME</PackageProjectUrl>\n    <PackageLicenseUrl>https://github.com/USER/PROJECT_NAME/blob/master/LICENSE</PackageLicenseUrl>\n    <RepositoryType>git</RepositoryType>\n    <RepositoryUrl>https://github.com/USER/PROJECT_NAME</RepositoryUrl>\n    <IncludeSymbols>True</IncludeSymbols>\n    <IncludeSource>True</IncludeSource>\n    <PackageOutputPath>$(MSBuildThisFileDirectory)Artifacts</PackageOutputPath>\n    <PackageOutputPath Condition=\" '$(BUILD_ARTIFACTSTAGINGDIRECTORY)' != '' \">$(BUILD_ARTIFACTSTAGINGDIRECTORY)</PackageOutputPath>\n    <IsTestProject>$(MSBuildProjectName.Contains('Test'))</IsTestProject>\n    <GenerateDocumentationFile>!$(IsTestProject)</GenerateDocumentationFile>\n    <GeneratePackageOnBuild>!$(IsTestProject)</GeneratePackageOnBuild>\n  </PropertyGroup>\n</Project>\n```","date_published":"2018-03-29T03:43:00.000Z","date_modified":"2018-05-15T09:46:51.000Z","tags":[".NET","Prism","Xamarin","NuGet"]},{"id":"https://dansiegel.net/post/2018/03/11/secure-app-builds-with-appcenter","url":"https://dansiegel.net/post/2018/03/11/secure-app-builds-with-appcenter","title":"Secure App Builds with AppCenter","summary":"AppCenter has been touted as this wonderful new service from Microsoft. It's supposed to make it easier to build, test and distribute our apps. While there is a...","content_text":"AppCenter has been touted as this wonderful new service from Microsoft. It's supposed to make it easier to build, test and distribute our apps. While there is a lot I love about AppCenter, the simplification of the Build pipeline over VSTS always seemed to be problematic to me. For years I have had a pet peeve that developers often check things into source control that should never be checked in. Sometimes it's simply a backend URL, other times it could be a Client ID. These sorts of things should never be checked in, and should be injected as part of the Build pipeline. The problem is that when you have only a very simple process in place for creating a new build it opens you up to make these sorts of poor decisions with your code base.\n\nFor those who are familiar with AppCenter you may be familiar with the fact that you can [add scripts](https://docs.microsoft.com/en-us/appcenter/build/custom/scripts/) to your projects:\n\n-   **appcenter-post-clone.sh** (Bash for iOS & Android)\n\n```bash\n#!/usr/bin/env bash\n\n# Example: Clone a required repository\ngit clone https://github.com/example/SomeProject\n\n# Example: Install App Center CLI\nnpm install -g appcenter-cli\n```\n\n-   **appcenter-pre-build.sh** (Bash for iOS & Android)\n\n```bash\n#!/usr/bin/env bash\n\n# Example: Change bundle name of an iOS app for non-production\nif [ \"$APPCENTER_BRANCH\" != \"master\" ];\nthen\n    plutil -replace CFBundleName -string \"\\$(PRODUCT_NAME) Beta\" $APPCENTER_SOURCE_DIRECTORY/MyApp/Info.plist\nfi\n```\n\n-   **appcenter-post-build.sh** (Bash for iOS & Android)\n\n```bash\n#!/usr/bin/env bash\n\nHOCKEYAPP_API_TOKEN={API_Token}\nHOCKEYAPP_APP_ID={APP_ID}\n\n# Example: Upload master branch app binary to HockeyApp using the API\nif [ \"$APPCENTER_BRANCH\" == \"master\" ];\nthen\n    curl \\\n    -F \"status=2\" \\\n    -F \"ipa=@$APPCENTER_OUTPUT_DIRECTORY/MyApps.ipa\" \\\n    -H \"X-HockeyAppToken: $HOCKEYAPP_API_TOKEN\" \\\n    https://rink.hockeyapp.net/api/2/apps/$HOCKEYAPP_APP_ID/app_versions/upload\nelse\n    echo \"Current branch is $APPCENTER_BRANCH\"\nfi\n```\n\n### Simplifying Builds\n\nWhile ridiculously powerful in what you can do with these scripts (I've been told you can install pretty much anything you want), this seems like far too much effort. I'll even admit that while I'm quite capable of writing whatever scripts I want, beyond a POC, I have never, and have no plans of writing scripts, to get my projects building on AppCenter. There are some things, that shouldn't require lots of work, just to make builds work from one project to another. This is where the Mobile.BuildTools comes in. The [Mobile.BuildTools](https://www.nuget.org/packages/Mobile.BuildTools) is an easy to use NuGet package. It simply adds tooling for MSBuild and has no binaries that are injected into your application. Because of this it can be used anywhere that you have MSBuild including Visual Studio, Visual Studio Mac, Visual Studio Code, or any Build Host including AppCenter. I have often referenced it as \"DevOps in a box\", or at least in a NuGet. I should probably add here, that it's called Mobile.BuildTools not just because you can use it on Mobile Apps. You can use this on literally ANY .NET Project, on ANY Platform supported by MSBuild.\n\n#### Setting Up Your Application\n\nAfter installing the NuGet, we can add a JSON file to our PCL or .NET Standard named `secrets.json`, like the following:\n\n```js\n{\n  \"AppCenter_iOS_Secret\": \"{Your Secret Here}\",\n  \"AppCenter_Android_Secret\": \"{Your Secret Here}\"\n}\n```\n\nNote that I've given it the rather long name here for illustrative purposes and to make it easier to read, but ultimately you can add as many keys as you want with whatever name you want. At build this will then automatically generate a Secrets class in your project's Helpers namespace. This will regenerate on each build, so any changes should be made to the JSON file and not the C# file. You should also add `secrets.json` and `Secrets.cs` to your `.gitignore`. If you're using my template packs, this is already done for you. \n\nI've gotten the question, what happens when I have some value that isn't a string? That's a fantastic question, and the Mobile.BuildTools has you covered there as well with support for string, int, double, and bool data types.\n\n#### Protecting Your App Manifest\n\nSometimes secrets don't limit themselves to some constant value in our App. Sometimes we need to declare something sensitive in either our `Info.plist` or `AndroidManifest.xml`. This creates an issue for us as well. We obviously need to be able to test locally, but again we need to ensure we don't check these files in with those sensitive values. The Mobile.BuildTools again have your back. By adding these files to our `.gitignore` we keep from checking in sensitive values. In truth most of these manifests really aren't all that sensitive. To make it simple though we can simply check in a tokenized version of these manifests. Note that by default tokens should are delimited by double dollar signs before and after the variable name such as `$$AppCenterSecret$$`.\n\n```plain\n| - MyProject.sln\n| - build/\n| - | - AndroidTemplateManifest.xml\n| - | - BuildTemplateInfo.plist\n```\n\n_Sample BuildTemplateInfo.plist_\n\n```xml\n<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n    <key>CFBundleDisplayName</key>\n    <string>AppCenter.DemoApp</string>\n    <key>CFBundleName</key>\n    <string>AppCenter.DemoApp</string>\n    <key>CFBundleIdentifier</key>\n    <string>com.appcenter.demoapp</string>\n    <key>CFBundleShortVersionString</key>\n    <string>1.0</string>\n    <key>CFBundleVersion</key>\n    <string>1.0</string>\n    <key>LSRequiresIPhoneOS</key>\n    <true/>\n    <key>MinimumOSVersion</key>\n    <string>8.0</string>\n    <key>UIDeviceFamily</key>\n    <array>\n        <integer>1</integer>\n        <integer>2</integer>\n    </array>\n    <key>UILaunchStoryboardName</key>\n    <string>LaunchScreen</string>\n    <key>UIRequiredDeviceCapabilities</key>\n    <array>\n        <string>armv7</string>\n    </array>\n    <key>UISupportedInterfaceOrientations</key>\n    <array>\n        <string>UIInterfaceOrientationPortrait</string>\n        <string>UIInterfaceOrientationLandscapeLeft</string>\n        <string>UIInterfaceOrientationLandscapeRight</string>\n    </array>\n    <key>UISupportedInterfaceOrientations~ipad</key>\n    <array>\n        <string>UIInterfaceOrientationPortrait</string>\n        <string>UIInterfaceOrientationPortraitUpsideDown</string>\n        <string>UIInterfaceOrientationLandscapeLeft</string>\n        <string>UIInterfaceOrientationLandscapeRight</string>\n    </array>\n    <key>XSAppIconAssets</key>\n    <string>Assets.xcassets/AppIcon.appiconset</string>\n    <key>CFBundleURLTypes</key>\n    <array>\n        <dict>\n            <key>CFBundleURLSchemes</key>\n            <array>\n                <string>appcenter-$$AppCenterSecret$$</string>\n            </array>\n        </dict>\n    </array>\n</dict>\n</plist>\n```\n\n#### Setting Up AppCenter For Builds\n\nKeep in mind here that our code now relies on a class called Secrets with several constants that exist nowhere in our codebase, and we have an iOS project without an Info.plist and an Android project without the AndroidManifest.xml... AppCenter offers us the ability to easily add Environment Variables. And this is where the build tools will be able to pick up what we need. \n\nThe Mobile.BuildTools are highly configurable based on preferences, but by default a common project type such as PCL or .NET Standard library will look for any variables prefixed with `Secret_`, while platform targets look for this with their name like `iOSSecret_` or `DroidSecret_`. Setting any of these in the build will generate a `secrets.json` and resulting Secrets class in the target project. I did of course say that we have a tokenized version of our manifests which have both the wrong name and tokens that need to be replaced. Just like with the secrets though the variables need to be prefixed, however the default prefix for this is simply `Manifest_`.  \n\n### Get Started\n\nTo get started install the Mobile.BuildTools into your project. These tools are free and open source, with documentation on additional configuration options that can be found on [GitHub](https://github.com/dansiegel/Mobile.BuildTools). If you have any issues or have a great idea that you would like to see added to the tools open an [issue](https://github.com/dansiegel/Mobile.BuildTools/issues/new).\n\nWant to see more? Be sure to check out the [demo app](https://github.com/dansiegel/AppCenter.DemoApp \"AppCenter Demo App\").","date_published":"2018-03-11T05:00:00.000Z","date_modified":"2018-03-11T12:09:51.000Z","tags":["Xamarin","AppCenter","DevOps"]},{"id":"https://dansiegel.net/post/2017/11/06/xamarin-devops-in-a-box","url":"https://dansiegel.net/post/2017/11/06/xamarin-devops-in-a-box","title":"Xamarin DevOps In A Box","summary":"Several Months ago I set out to make some of the most powerful Xamarin Project Templates. I've gotten a lot of feedback on the Prism QuickStart Templates and how...","content_text":"Several Months ago I set out to make some of the most powerful Xamarin Project Templates. I've gotten a lot of feedback on the [Prism QuickStart Templates](/post/2017/07/16/prism-quickstart-templates) and how they have accelerated Mobile Development for Developers. One of the features that has really caught the attention of so many developers is the Application Secrets generation. Mobile Apps so often have sensitive information such as Client Id's, or builds that require some minor changes such as pointing to one backend API for Development, another for Staging, and yet another for Production. The custom tasks that have been included in the QuickStart Templates have been helping developers for months to more easily handle these tasks.\n\nOver time as I've made changes and improvements I've come to realize that it has left existing projects in a state where they have been unable to take advantage of changes. There has also been the fact that while they have been tied exclusively to the Prism QuickStart Templates though there is nothing about these great Build Tasks that are tied in any way to Prism. These wonderful Build Props and Build Targets have been separated out into an easy to install NuGet. Since this only contains build props and targets it adds nothing to the size of assemblies, but it does make your DevOps a whole lot easier.\n\n### Build Props\n\nWhile many developers may not currently be utilizing many Build Props, the Mobile.BuildTools adds a number of properties that help you determine what type of project is building and on what type of Host. This could for example better assist you in developing Build tasks that only execute on Windows or Mac, determine if PowerShell is installed. You can also easily determine what platform the project is. We'll take a look at an example below.\n\n### Build Secrets\n\nModern apps are full of Client Id's, and Secrets that it can be maddening for Security. After all how do you develop an app that requires this type of sensitive information without compromising security by checking code into Source Control that contains our Id's and Secrets? Better yet how can we develop better CI/CD pipelines that are customized for an environment such as Development, Staging, or Production? This is where the Secrets Task shines. By simply including a file named `secrets.json` in your project root, the Secrets Task will generate a Secrets class for you. This enables you to ignore both the `Secrets.cs` and `secrets.json` files in your .gitignore. This frees your Build Server to generate your secrets.json and the rest is handled for you.\n\n### Templating Project Manifests\n\nSometimes our DevOps process requires having flexibility across our app manifests. While I am sure there are a multitude of reasons for why you might have this requirement the two most common use cases I see are:\n\n-   I am developing an Application that must be tweaked for multiple customers and deployed to the App Store for each (i.e. a Banking App)\n-   My application requires a setting in my manifest that exposes a Client ID or some other sensitive piece of information (i.e. I am using the Microsoft.Identity.Client for Azure Active Directory)\n\nThis is another area where the Mobile.BuildTools really shines by allowing you to include safe to check in Manifest Templates which will then be appropriately copied to your iOS or Android project. As I mentioned before this is just a sample of how the Build Props can better assist your DevOps. Each Copy task is restricted so that the AndroidManifest.xml is only copied when IsAndroidProject is true, and the Info.plist is only copied when IsiOSProject is true. \n\n### FAQ\n\nQ. What happens if I don't have a secrets.json included in my Project?  \nA. Nothing. The Task will safely execute, not having found a secrets.json file and will finish without creating anything.\n\nQ. Can I name secrets.json something else?  \nA. Yes, it is a configurable Property. You can add JsonSecretsFileName to the PropertyGroup of your Project with the file name it should look for.\n\nQ. Can you have secrets in more than one Project?  \nA. Yes, you can have secrets in as many projects as you want. Again the Task will only generate the Secrets class if you have a secrets.json present.\n\nQ. The idea of a Tokenized Manifest sounds cool, but I don't need it. Can I still use the BuildTools?  \nA. Yes! As long as the AndroidManifest.xml or Info.plist is present when the Build is started it will not copy them over. Otherwise it would get really annoying during development to get some Tokenized manifest constantly undoing your changes.\n\nQ. How do I find out more about setting up the Manifest Templates? Is is customizable?  \nA. You can find out more on [GitHub](https://github.com/dansiegel/Mobile.BuildTools). You can override the default variables to change the location of the templates, and even the Template Names. \n\nQ. Am I able to swap out the appxmanifest on UWP?   \nA. UWP is not currently handled by default, however you can easily add support by adding `ManifestDestinationPath` and `TemplateManifestPath` to the PropertyGroup in your UWP Project.\n\nQ. Does it work on with Visual Studio and Visual Studio for Mac?  \nA. Yes it work on both Mac and Windows. As part of migrating this out of the templates, the tasks have been upgraded to compiled tasks meaning it works with MSBuild without any additional requirement for PowerShell.\n\n### Getting Started\n\nFor existing QuickStart Template Projects, you will need to delete the Directory.build.props and Directory.build.targets. You can also delete the PowerShell scripts. To get started, simply install the [Mobile.BuildTools](https://www.nuget.org/packages/Mobile.BuildTools/) NuGet into any project you need to generate App Secrets or an iOS/Android project that you want to be able to swap out the Manifest for.","date_published":"2017-11-06T12:53:00.000Z","date_modified":"2017-11-15T21:27:00.000Z","tags":["Prism","Xamarin","DevOps"]},{"id":"https://dansiegel.net/post/2017/10/13/prism-for-xamarin-forms-preview-3","url":"https://dansiegel.net/post/2017/10/13/prism-for-xamarin-forms-preview-3","title":"Prism for Xamarin Forms Preview 3","summary":"So much goes into developing a Xamarin Forms application, and Prism for Xamarin Forms is continuing to make your mobile development a little easier. Today we...","content_text":"So much goes into developing a Xamarin Forms application, and Prism for Xamarin Forms is continuing to make your mobile development a little easier. Today we released Preview 3 for Prism 7, and a lot has happened since I published the [Sneak Peak](/post/2017/07/19/prism-7-0-for-xamarin-forms-sneak-peek) and the changes to [Autofac](/post/2017/08/02/breaking-changes-for-prism-autofac-users).\n\n## Navigation\n\nOne of the big things developers love about Prism is Deep Linking like `\"NavigationPage/ViewA/ViewB/ViewC\"`. Unfortunately this also exposes a bug in Xamarin Forms which the Xamarin team hasn't fixed. The result has been that the Title displayed in the NavigationPage is for ViewA rather than ViewC. Prism 7 has finally fixed this issue so that deep linking can still occur properly.\n\nA long awaited feature is Relative Navigation. We see this all the time in web development, and beginning with preview 3 you can now simplify our Navigation like \"../SomePage\". This will both pop the current page and add SomePage to the Navigation Stack. Keep in mind that this feature will only work within the context of a NavigationPage. \n\nAnother long await feature has been the ability to simply go back to the root. Prism's Navigation Service now includes a GoBackToRootAsync extension that will support this exact use case. \n\n## TabbedPages\n\nPrism 7 has a lot of fixes to make working with TabbedPages a joy. In past versions of Prism we've had to both explicitly set the `ViewModelLocator.AutowireViewModel` property on any pages that will be children of a TabbedPage, and we've had to create a TabbedPage that explicitly sets the tabs.\n\n```xml\n<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<TabbedPage xmlns=\"http://xamarin.com/schemas/2014/forms\"\n            xmlns:x=\"http://schemas.microsoft.com/winfx/2009/xaml\"\n            xmlns:local=\"clr-namespace:AwesomeApp.Views;assembly=AwesomeApp\"\n            x:Class=\"AwesomeApp.Views.MyTabbedPage\">\n\n    <local:ViewA />\n    <local:ViewB />\n    <local:ViewC />\n\n</TabbedPage>\n```\n\nBeginning with Prism 7 you can now simply register the Xamarin Forms TabbedPage for Navigation and simply navigate like `\"TabbedPage?createTab=ViewA&createTab=ViewB&createTab=ViewC\"`. But it doesn't stop there. There are times that we want to use a NavigationPage for a particular tab. We can now easily do this by adding the pipe character and navigating like: `\"TabbedPage?createTab=ViewA&createTab=NavigationPage|ViewB&createTab=ViewC\"`. Best of all is that the NavigationService now better handles the children so that whether you have a traditional TabbedPage like above or one generated from the querytstring your pages will be automatically get the `ViewModelLocator.AutowireViewModel` set, and any Prism Behaviors will also automatically be set.\n\nThere has also been a major breaking change for selecting the active tab. In previous versions of Prism for Xamarin Forms you could set the active tab by adding the tab to select as the next Uri segment `\"MyTabbedPage/ViewB\"`. This has been changed in preference of a querystring parameter like `\"TabbedPage?selectedTab=ViewB\"`. Note that for those who are concerned about magic strings, we've got you covered as this is all based on the constants in KnownNavigationParameters. Putting this all together you can now navigate like:\n\n```csharp\n_navigationService.NavigateAsync($\"TabbedPage?{KnownNavigationParameters.CreateTab}=ViewA&{KnownNavigationParameters.CreateTab}=ViewB&{KnownNavigationParameters.CreateTab}=ViewC&{KnownNavigationParameters.SelectedTab}=ViewC\");\n```\n\n## Lifecycle\n\n`IActiveAware` has been around Prism for some time but has only had limited support to handle when a page becomes the current page inside of a TabbedPage or CarouselPage. A new interface has been added to Prism.Forms called IPageLifecycleAware. This is handled through a Behavior added to every page by the NavigationService which will allow you to respond to the Appearing and Disappearing events.\n\nSticking with being Lifecycle aware, preview 3 has introduced a breaking change from earlier previews with `IApplicationLifecycle` to `IApplicationLifecycleAware`. While there hasn't been any actual changes to the way it works, it does better fit the naming conventions in Prism.\n\n## Modularity\n\nModularity has long been a core concept in Prism. Modularity has gotten a whole lot nicer in Prism 7 with a few fixes. To start with IModuleCatalog was fixed to properly return IModuleCatalog rather than ModuleCatalog when adding a Module. One of the problems with adding Modules in previous versions has been the verbosity that was required:\n\n```csharp\nModuleCatalog.AddModule(new ModuleInfo(nameof(SomeModule), typeof(SomeModule), InitializationMode.WhenAvailable));\n```\n\nThis can now be simplified like:\n\n```csharp\n// Basic Registration\nModuleCatalog.AddModule<SomeModule>();\n```\n\nThere are of course some overloads to specify either the name or Initialization Mode. We have also added extensions to better determine whether a Module has been added to the ModuleCatalog and what the ModuleState is.","date_published":"2017-10-13T05:53:00.000Z","date_modified":"2017-10-13T15:06:38.000Z","tags":["Prism","Xamarin","Xamarin Forms"]},{"id":"https://dansiegel.net/post/2017/10/10/xamarin-forms-ui-development-made-easy-with-livexaml","url":"https://dansiegel.net/post/2017/10/10/xamarin-forms-ui-development-made-easy-with-livexaml","title":"Xamarin Forms UI Development Made Easy with LiveXAML","summary":"I'm all about working with XAML in my Xamarin Forms apps. Developers coming from a WPF background have been used to some great tooling for visually styling their...","content_text":"I'm all about working with XAML in my Xamarin Forms apps. Developers coming from a WPF background have been used to some great tooling for visually styling their XAML for years. Xamarin Forms of course isn't so cut and dry for the obvious reason that we're dealing with an Abstraction of the UI. Chances are you've probably heard about Xamarin's Live Player. To be honest I think it's a cute idea, but really lacks what you need to be most productive. \n\nNaturally one of the biggest pains when working with XAML is getting the Styling just right. We do have more tools now at our disposal like the XAML Previewer in Visual Studio and Visual Studio Mac, but it lacks the touch and feel component of styling. This is where LiveXAML is making a huge difference in developing Xamarin Forms applications. LiveXAML not to be confused with Xamarin's Live Player, allows you to get the updates directly in your actual app. LiveXAML is truly one of the most amazing products I've ever worked with for XAML. \n\n![Xamarin Forms UI Development Made Easy with LiveXAML](/images/blog/xamarin-forms-ui-development-made-easy-with-livexaml/01-image.gif)\n\nIt really is as simple as installing a single NuGet package and running the application in your Simulator or on your Device. Now you can actually see what your changes are doing, without rebuilding, in an app that is fully functional. There are no short cuts, no limitations like we see with the Live Player or the Previewer.\n\nThere are a number of challenges that are hard to handle without a data context behind them. One of them is handling a ListView with a DataTemplateSelector. It's certainly one thing to refine a single ViewCell, but when you have multiple cells that each need to be styled there is no substitute for having real working data which can only happen with your app actually running. This is one the many scenarios where using LiveXAML can really shine as you quickly update the styling and see the changes in your app. \n\nIf you haven't had a chance to check it out head over to [http://livexaml.com](http://livexaml.com/).","date_published":"2017-10-10T02:00:00.000Z","date_modified":"2017-10-10T08:55:14.000Z","tags":["Xamarin","Xamarin Forms","XAML","LiveXaml"]},{"id":"https://dansiegel.net/post/2017/08/30/prism-template-pack-in-visual-studio-for-mac","url":"https://dansiegel.net/post/2017/08/30/prism-template-pack-in-visual-studio-for-mac","title":"Prism Template Pack in Visual Studio for Mac","summary":"Prism users have long enjoyed some great Template packs available for Visual Studio and Xamarin Studio. Visual Studio for Mac though has been a real challenge...","content_text":"Prism users have long enjoyed some great Template packs available for Visual Studio and Xamarin Studio. Visual Studio for Mac though has been a real challenge due to problems with the Mono Addins site not building the Prism Addin. It's been a very common request among our Mac users to get this support back.\n\nSince we have been unable to rely on the Mono Addins site, we have decided to simply host our own feed for Prism Users. This new feed will allow you to add and update the Prism Template Pack in Visual Studio for Mac.\n\nSo how do you get the Template Pack? Well for starters you will need to add the Prism feed to your Extensions Repositories. Once you have it added, simply refresh the Gallery. You can either use the search bar or expand `IDE extensions` to find the Prism Template Pack.\n\n![Prism Template Pack in Visual Studio for Mac](/images/blog/prism-template-pack-in-visual-studio-for-mac/01-image.webp)\n\n![Prism Template Pack in Visual Studio for Mac](/images/blog/prism-template-pack-in-visual-studio-for-mac/02-image.webp)\n\n![Prism Template Pack in Visual Studio for Mac](/images/blog/prism-template-pack-in-visual-studio-for-mac/03-image.webp)\n\nKeep in mind that the new Prism Template Pack for Visual Studio for Mac now includes a DryIoc Project template in addition to the Unity Template. Both project templates will create project with the latest stable versions of Prism and Xamarin Forms.","date_published":"2017-08-30T05:12:00.000Z","date_modified":"2017-08-30T15:14:07.000Z","tags":["Prism","Xamarin","Xamarin Forms","templates"]},{"id":"https://dansiegel.net/post/2017/08/02/breaking-changes-for-prism-autofac-users","url":"https://dansiegel.net/post/2017/08/02/breaking-changes-for-prism-autofac-users","title":"Breaking Changes for Prism Autofac Users","summary":"History It's certainly been no secret that I've told user's that Autofac wasn't really a good choice for Prism Forms. To be honest just looking at the benchmarks...","content_text":"## History\n\nIt's certainly been no secret that I've told user's that Autofac wasn't really a good choice for Prism Forms. To be honest just looking at the benchmarks between Autofac and DryIoc or SimpleInjector which may soon be supported, Autofac just isn't that appealing to me. The truth though, is that I wasn't just steering people away from Prism Autofac for this reason alone.\n\nBefore Prism introduced .NET Standard support, we were limited to targeting Autofac 3.5. As anyone familiar with Autofac is likely aware, the `ContainerBuilder.Update(Container)` method was deprecated. Autofac quite annoyingly wants to be an immutable container. This is problematic for frameworks like Prism, or any developer who wants to dynamically load dependencies (more on this later). Also part of the problem was that Autofac is a bit unique in the way that it handles registering and resolving. Most containers are responsible for registering dependencies, telling you if something is registered, and resolving that dependency, but Autofac wants to be different with a `ContainerBuilder` that is used for registering, a central `IContainer` that knows nothing about itself, but is happy to resolve `IComponentContext` if you need to inject something into a class to resolve dependencies in a factory method like the one used by the NavigationService to resolve your Views... \n\n## Major Breaking Changes\n\nPrism Forms is architected for a Container that knows how to do stuff, continuing to have the Autofac `PrismApplication` derive from `PrismApplicationBase<IContainer>` was a poor choice. To help fix the way Autofac works with Prism Forms this was updated to `PrismApplicationBase<ContainerBuilder>`. That alone though would provide for a poor experience so this was updated to ensure that the Container property is still the `IContainer` that is set when the builder is built, and a Builder property was added to give you direct access to the `ContainerBuilder` being used in `PrismApplication` to register all of the Prism services. Unlike the builder previously used by PrismApplication, this builder waits to call `Builder.Build()` until after it registers the base Prism services, anything in your `RegisterTypes()` and anything in your `IPlatformInitializer`.\n\nTo make this work though, we also had to break all of your View Registrations. The extension methods that we typically include in Prism Forms are based on the Container for registrations. But this never made sense for Autofac, leading to extension methods that would create a builder, and then update the Container. To better align with the intent of how Autofac is meant to work the methods were updated to be based on the ContainerBuilder.\n\n```csharp\npublic class App : PrismApplication\n{\n    protected override void RegisterTypes()\n    {\n        Builder.RegisterType<Foo>().As<IFoo>();\n        Builder.RegisterTypeForNavigation<ViewA>();\n    }\n}\n\npublic class iOSInitializer : IPlatformInitializer\n{\n    public void RegisterTypes(ContainerBuilder builder)\n    {\n         builder.RegisterType<SpeakImp>().As<ISpeak>();\n    }\n}\n```\n\n## Modularity\n\nModularity hasn't been huge in the Prism Forms community like it is in the WPF community. For developers who are familiar with it, Modules are often a major part of their app development. Unfortunately Autofac's desire to be immutable poses some major problems for Modularity with Prism. Prism relies on container mutability for Modules. Part of this is that we must resolve the ModuleCatalog before we run it and initialize any of the Modules. The other part is that Prism allows us to load Modules on demand. This could for instance allow us to ship an application like Lyft and only load the Driver Module if the user is a Driver. Since Autofac is immutable this creates a major problem for us, and OnDemand Modules are out of the question due to the limitations imposed on us by the container. As such the recommended guidance for Autofac users will be to architect modules as follows:\n\n```csharp\npublic class AwesomeModule : IModule\n{\n    public void Initialize() { }\n\n    public static void Initialize(ContainerBuilder builder)\n    {\n        builder.RegisterType<FooService>().As<IFooService>();\n        builder.RegisterTypeForNavigation<ViewA>();\n    }\n}\n\npublic class App : PrismApplication\n{\n    protected override void RegisterTypes()\n    {\n        // Initialization must be done before the Container is built.\n        AwesomeModule.Initialize(Builder);\n    }\n\n    protected override void ConfigureModuleCatalog()\n    {\n        // Not actually needed for Autofac since all registrations must be done\n        // before we build the container.\n    }\n}\n```\n\n## Getting Started\n\nThese changes are all available starting with Prism 7.0.0.30-ci in the [Prism MyGet feed](https://myget.org/gallery/prism). If you have not already done so, you can add that feed in either Visual Studio or Visual Studio for Mac and update your existing Prism Application's to the latest CI build. \n\nIf you are starting with a new Project you will want to check out the updated [QuickStart Templates](/post/2017/07/16/prism-quickstart-templates) which now includes the only Module project template, and full support for the updated Autofac implementation.","date_published":"2017-08-02T00:32:00.000Z","date_modified":"2017-08-02T10:25:02.000Z","tags":["Prism","Xamarin","Autofac"]},{"id":"https://dansiegel.net/post/2017/07/19/prism-7-0-for-xamarin-forms-sneak-peek","url":"https://dansiegel.net/post/2017/07/19/prism-7-0-for-xamarin-forms-sneak-peek","title":"Prism 7.0 for Xamarin Forms Sneak Peek","summary":"Prism 7.0 Sneak Peek If you're a Xamarin developer, chances are you've been through a struggle or two with NetStandard. NetStandard offers a lot of advantages,...","content_text":"If you're a Xamarin developer, chances are you've been through a struggle or two with NetStandard. NetStandard offers a lot of advantages, but support has been slow going in many cases. Xamarin Forms only recently began shipping NetStandard. Prism users have been asking for a while now to have NetStandard support. Obviously for WPF users NetStandard really doesn't offer any advantages, and for UWP it just creates a few headaches, but that hasn't stopped requests for the Core to support NetStandard or for Prism Forms to be converted. For a while now I've been either pointing people to my preview templates or telling them to use the PackageTargetFallback attribute with the new csproj format. Well, I'm happy to say that Prism for Xamarin Forms is now available in NetStandard!\n\n![Prism 7.0 for Xamarin Forms Sneak Peek](/images/blog/prism-7-0-for-xamarin-forms-sneak-peek/01-image.webp)\n\nWhile NetStandard support is fantastic, I probably wouldn't take the time to write a post just about that. One of the problems we all face is when we run into an issue with a library in our code base, and the issue is fixed on GitHub. The problem is that it may be days, weeks, even months before it is available. So suddenly you have to uninstall the NuGet packages, add the open source library as a git submodule. As Prism moves into the 7.0 update, I'm also very happy to announce the official Prism MyGet feed that is tied into the builds so when new features are added you can immediately expect a new CI package available on MyGet so you can immediately start using the features you need without having to wait for an official release. \n\n```bash\nhttps://www.myget.org/F/prism/api/v3/index.json\n```\n\n## Whats New Since 6.3\n\nYou may be thinking that NetStandard is great and all but that isn't really new. As part of Prism updating to Xamarin Forms 2.3.5, you will now have full support for working with Prism on macOS applications. \n\nAnother change you can look for starting now in the 7.0 addresses the overhauled OnPlatform starting in Xamarin Forms 2.3.4. Unfortunately the new Xamarin API for OnPlatform uses magic strings, and is cumbersome to say the least if you're working with it from C# code and not in XAML. Prism has updated the IDeviceService and provided a new RuntimePlatform enum. We have also updated Platform dependent View Registrations to use this new RuntimePlatform enum. This will ultimately be a lot cleaner than the previous type based registrations.\n\n```csharp\nContainer.RegisterTypeForNavigationOnPlatform<MainPage, MainPageViewModel>(\"Main\",\n     new Platform<MainPage_Android>(RuntimePlatform.Android),\n     new Platform<MainPage_iOS>(RuntimePlatform.iOS));\n```\n\nFollowing the deprecation of the previous OnPlatform functions within the Xamarin Forms Device class, we have updated `IDevice` to deprecate this feature as well and added access both the Xamarin Forms Platform string and our RuntimePlatform enum.\n\nI have been a huge advocate for directly binding to your model's properties. It really saves a lot of headaches with validation and ensuring that changes made on the view update your model to be persisted to your data store. That said even with Prism's DelegateCommand.ObservesProperty, this has been a shortcoming. Thanks to a community contribution this will now be possible in Prism 7.0\n\n```csharp\nObservesProperty(() => Property.NestedProperty.NestedPoperty)\n```\n\nAnother major improvement addresses exceptions thrown during navigation. Prism Forms will now properly log and re-throw exceptions that are thrown when you're navigating. This has been a major pain point in the past where the exceptions were effectively swallowed by the NavigationService and you had no idea what threw an exception or even what the exception was. Many times you might have simply found yourself getting an exception thrown because your MainPage was null and the platform excepted something. \n\nThere have also been a number of reported Navigation Bugs fixed in Prism 7.\n\n### Prism for UWP Developers\n\nIf you're developing UWP applications with Prism there are a couple of gotcha's that you'll need to know about. \n\nStarting in Prism 7.0 we've decided to split all of the Platforms/Containers into separate packages. We've done this so that we can rev the platforms separately from one another, and if we update an issue with `Prism.Autofac.Wpf`, `Prism.Autofac.Windows` user's won't see a package update and think that something changed. This only affects UWP developers who are using Prism for UWP. You simply need to uninstall the `Prism.{Container}` package and install the `Prism.{Container}.Windows` package. (note that this update is not yet available but will be soon)\n\nWhether you're using Prism for UWP or Prism for Xamarin Forms, note that there is a bug with the .NET SDK that will affect you if Prism 7 is the first NetStandard package that you are using. It is easily overcome by adding the file `Directory.Build.props` next to your solution file, with the following contents:\n\n```xml\n<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project>\n  <!-- Workaround for https://github.com/dotnet/sdk/pull/908 -->\n  <Target Name=\"GetPackagingOutputs\" />\n</Project>\n```\n\nNote that if you are developing a UWP application with the Prism QuickStart Template for Xamarin Forms, this has already been added for you.\n\n## Whats Coming\n\nAs amazing as NetStandard is to finally have behind us, I'm still even more excited by what's coming in 7.0. I wouldn't call this an exhaustive list, but here are some highlights of some features to keep an eye out for in Prism 7:\n\n-   Querystring navigation is one of the most amazing things about the Prism Navigation Service, and it's about time that you should be able to dynamically create tabs or use modal navigation through the querystring.\n-   Removal of support for the Xamarin Forms DependencyService. This really leads to some bad practices, and with `IPlatformInitializer` there is simply no need to rely on the Dependency Service for Platform specific types.\n-   An ability to use MVVM and the ViewModelLocator with custom Views as well as Xamarin Forms Pages.","date_published":"2017-07-19T04:00:00.000Z","date_modified":"2017-07-20T07:48:50.000Z","tags":["Prism","Xamarin","netstandard"]},{"id":"https://dansiegel.net/post/2017/07/16/prism-quickstart-templates","url":"https://dansiegel.net/post/2017/07/16/prism-quickstart-templates","title":"Prism Quickstart Templates","summary":"Quickstart Templates for Prism Forms So you had this great idea for an app... maybe you spent weeks planning with your team or with your client. The day finally...","content_text":"## Quickstart Templates for Prism Forms\n\nSo you had this great idea for an app... maybe you spent weeks planning with your team or with your client. The day finally comes to create the project. Suddenly you realize that we have this new .NET Standard thing and you want to take advantage of that too. You remember you need icons, you want a Splash Screen... all of the things that go into making an App. For anyone who has done this, you know there's a lot of heavy lifting to be done. In all honesty you could easily spend several days just getting a new project from File -> New to something that you're ready to start working on.\n\nIt was for this and so many other reasons that I realized we need better templates, and we need something that can help us whether we're on a Mac or on PC.\n\nThere are some very basic things left out of the base Xamarin & Prism Templates. For some developers these just require time that could be better spent on something else, and for other developers it leads them down a path of poor design.\n\n## Features\n\nWhy should you use these templates? Well here are a couple bullet points:\n\n-   Gets you off the ground following Best Practices\n-   \\*Starts you off using Prism for Xamarin Forms with either DryIoc or Unity for Dependency Injection\n-   Already has all of your App Icons added so all you need to do is drop in the replacement files from File Explorer or Finder. There is also a link in there so you can see how to get all of your icons generated for you correctly in all of the sizes with all of the correct naming.\n-   Starts you off with some base colors to use for your project with information of how to develop a Material Design pallet for your application.\n-   By default it already has everything you need for Localizing strings in XAML\n-   It's cross platform, using `dotnet new` you get the same experience from the command line whether on Mac or PC.\n-   Item templates to generate Views and ViewModels with support for the common Xamarin Forms pages as well as PopupPages\n-   Makes it easier to inject variables at Build to protect sensitive project secrets.\n-   Quickstart with a fully working Todo app working with in memory data, Realm, or Azure Mobile Client\n-   Included config for [MFractor](https://www.mfractor.com/products/mfractor-for-visual-studio-mac)\n\n\\*NOTE: Autofac & Ninject will be reintroduced once Prism 7 has a public preview.\n\n### Best Practices\n\nApp development can be simultaneously fun and frustrating. So many developers love Xamarin Forms because it really narrows down the number of API's you need to work with. What it doesn't do is eliminate your need to understand the platform your application will run on. These templates will not eliminate that need either, however they do set you down the right path, with some basic things like a splash screen so your user will at least see something while your app loads. Also included by default is the MVVM Helpers library from James Montemagno so that you can use his `ObservableRangeCollection<T>` to reduce the notifications sent to the UI when updating or replacing multiple items in your collection. If you don't use it MVVM Helpers you still get a `ViewModelBase` that will incorporate these properties as well as well as `IDeviceService` and virtual implementations of `INavigationAware`, `IActiveAware`, and `IApplicationLifecycle`.\n\n### Prism\n\nContinuing really with Best Practices, these templates use Prism for Xamarin Forms. Currently the templates support DryIoc and Unity for Dependency Injection. Autofac and Ninject will be added back in once there is a publicly available release of Prism 7.\n\n#### TabbedPages\n\nWorking with TabbedPages has traditionally been one of the more challenging areas of working with Prism. With the QuickStart template this challenge disappears. The template includes two base implementations for a TabbedPage, the `PrismTabbedPage` and the `DynamicTabbedPage`. If your TabbedPage inherits from PrismTabbedPage, it will automatically pick up and pass on the NavigationParameters to the Child Pages allowing you to properly initialize them. If you use the DynamicTabbedPage you only need to reference it in your Navigation URI and pass in variables like:\n\n```csharp\nNavigationService.NavigateAsync(\"TabbedPage?tab=ViewA&tab=ViewB&tab=ViewC\");\n```\n\nBut it actually gets a little better than that because not only does it pick up tabs but you can also do some deep linking like:\n\n```csharp\nNavigationService.NavigateAsync(\"TabbedPage?tab=NavigationPage/ViewA/ViewD&tab=NavigationPage/ViewB&tab=ViewC\");\n```\n\nThis means you can actually support scenarios where your actual tabs contain their own NavigationStack independent of the rest of the application.\n\n### App Icons\n\nApplications need a lot of icons and really the templates out there don't do a very good job with App Icons. Most templates out there just leave your deployed app with a broken icon image and require some time getting the icons setup. These templates start you off with icons for your Android and iOS projects. But more than that is the GettingStarted document included in the template gives you the information you need to be able to quickly and efficiently generate a full icon set that you can drop in to replace the default icons with your own icons. Following along with Best Practices, you'll find that the iOS project is using the newer appiconset approach with the app icons as ImageAssets rather than having them in the Resources folder as BundleResources. Similarly on Android you'll find the app icon's are all in the mipmap folders rather than drawable.\n\n### Material Design\n\nWhile my purpose is not to teach Material Design, there are some basics that we can easily include in the template to get you started down the right path. That includes a basic color pallet with information of how to choose new colors. There is also already a Style defined for you to customize the look and feel of a NavigationPage using those colors.\n\n### Localization\n\nOne of the things I hear over and over, developers in the United States forget some people don't speak English. For most US based dev's Localization is a complete and total afterthought. Interestingly nobody seems to have thought previously that maybe we should provide a template that assumes you want your application easily consumable by people in another country who speak another language. The quickstart template comes complete with all of the helper classes you need to get Localization working in the application and gets the Localization implemented with the DI container using Prism's `IPlatformInitializer`. There is also a XAML extension provided so all you need to do is include the namespace in your XAML file and use it as needed. The app of course also includes a single Resx file to get you started. You simply need to add the string resources you want to use in your application.\n\n### Cross Platform\n\nIt might seem weird when we're talking about Xamarin, but seriously it gets frustrating when we're working with a Cross Platform technology and then the developer experience is completely and totally different depending on which platform you are on. One of the most common issues we can see from a templating standpoint is that if I click `File -> New`, it shouldn't matter whether I'm on Mac or PC, I should be able to decide if I want my project to include iOS, Android, UWP. That's not to say I don't understand that some time may be needed before you can build a UWP app on Mac, but you should at least be able to have the platform as an option so you can work on the codebase from either platform.\n\n### Item Templates\n\nAlso included are some Item Templates custom built for the included project templates. There are two basic types of Item Templates, Pages and Services. Note that there is currently no way for the dotnet templating engine to pick up what your base namespace is, so you do have to specify this from the command line.\n\n#### Pages\n\nBy default when you call `dotnet new prismitem` you will get a page. It's assumed that you're using the ViewModelBase from the included Project templates. You can add flags to specify whether you want to implement `INavigatingAware`, `INavigatedAware`, `INavigationAware`, `IActiveAware`, or `IDestructible`. By default it implements `INavigationAware`. There is also a flag to indicate if the page is a Tabbed Child which will automatically implement `IActiveAware` and `INavigatingAware`. Currently supported page types include ContentPage, MasterDetailPage, TabbedPage (which inherits from the Quickstart PrismTabbedPage), and PopupPages.\n\n_Samples_\n\n```bash\ndotnet new prismitem -namespace MyAwesomeApp -n LoginPage\ndotnet new prismitem -namespace MyAwesomeApp -page PopupPage -n SomePage\ndotnet new prismitem -namespace MyAwesomeApp -n CustomerDetailPage -child\n```\n\n#### Services\n\nChances are your app is probably using some sort of service and if you like testability like I do, then you'll really appreciate that you can create a service with Mock class that will automatically be picked up by the Quickstart template simply by building with the Mock configuration. \n\n_Samples_\n\n```bash\ndotnet new prismitem -item Service -namespace MyAwesomeApp -n LoginService\ndotnet new prismitem -item Service -namespace MyAwesomeApp -n LoginService -mocks false\n```\n\n### Secrets\n\nAll apps have secrets and other variables that we just don't want checked into source control. To better assist with this, the template includes some helpers that will regenerate the `Secrets.cs` with sensitive variables you want in your codebase. Both the `Secrets.cs` and `secrets.json` files have also been added to the included `.gitignore`, so you can finally develop apps without having to tackle the issue of keeping app secrets out of SCM.\n\n_secrets.json_\n\n```js\n{\n  \"AuthClientId\": \"{Your App Client Id}\",\n  \"AppServiceEndpoint\": \"https://appservicename.azurewebsites.net/\"\n}\n```\n\n_Secrets.cs_\n\n```csharp\nnamespace YourProject.Helpers\n{\n    internal static class Secrets\n    {\n        internal const string AuthClientId = \"{Your App Client Id}\";\n\n        internal const string AppServiceEndpoint = \"https://appservicename.azurewebsites.net/\";\n    }\n}\n```\n\n### PropertyChanged.Fody\n\nPart of the MVVM pattern is working with `INotifyPropertyChanged`. Unfortunately the code can get a bit tedious. \n\n```csharp\npublic class ViewAViewModel : BindableBase\n{\n    private string _title;\n    public string Title\n    {\n        get => _title;\n        set => SetProperty(ref _title, value);\n    }\n\n    private MyModel _selectedItem;\n    public MyModel SelectedItem\n    {\n        get => _selectedItem;\n        set => SetProperty(ref _selectedItem, value, onChanged: OnSelectedItemChanged);\n    }\n\n    private void OnSelectedItemChanged()\n    {\n        // Do Stuff\n    }\n}\n```\n\nWith PropertyChanged.Fody already included our ViewModels and other Observable objects simply become:\n\n```csharp\npublic class ViewAViewModel : BindableBase\n{\n    public string Title { get; set; }\n\n    public MyModel SelectedItem { get; set; }\n\n    private void OnSelectedItemChanged()\n    {\n        // Do Stuff\n    }\n}\n```\n\n### Mobile Center\n\nAlso bundled into this template is support for the Azure Mobile Center. While this is an opt in feature you can pass in your App Secret for iOS and/or Android from the command line with everything already wired up to send your analytics and crash data to the Azure Mobile Center. This includes an implementation of `ILoggerFacade` that will create a Mobile Center Analytics Event.\n\n### Data Providers\n\nApps today are so often really connected apps. The Quickstart Template provides you a fully functional TodoApp with the option to use either the Azure Mobile Apps Client with [AzureMobileClient.Helpers](/post/2017/05/23/azure-mobile-client-helpers) or to use Realm. Either data provider will start you out with the ability to quickly develop your app with full online/offline sync with the bare minimum of configuration. \n\n#### Azure Mobile Client\n\nIn addition to simply using the Azure Mobile Client you can additionally decide if you want to use anonymous authentication or if you will require some sort of authentication. If you choose an authentication provider, the Quickstart will provide you base classes for everything you need to get started. This includes scaffolding for custom authentication sources and a fully working implementation for Azure Active Directory B2C with support coming for AAD, Google, Facebook and Microsoft Accounts.\n\n### Plugins\n\nBecause the full working app uses a PopupPage for the TodoItem detail page, the Quickstart includes [Prism.Plugin.Popups](https://github.com/dansiegel/Prism.Plugin.Popups), and also optionally includes a [Barcode Scanning Service](https://github.com/dansiegel/BarcodeScanner) utilizing [ZXing.Net.Mobile](https://github.com/Redth/ZXing.Net.Mobile) and is fully registered and configured.\n\n### Getting Started\n\nTo get started with the templates it's recommended that you install version [2.0 pre3 of the dotnet cli](https://github.com/dotnet/cli/tree/release/2.0.0) as this contains several fixes in the templating engine. Once that is installed you can install the templates by using the following commands in your cli.\n\n```bash\ndotnet new -i \"Prism.Forms.QuickstartTemplates::*\"\n```\n\nYou should see the `prismitems` and `prismformsempty` templates. The Quickstart template is grouped with the empty template, though you may not see it listed it is still there.\n\n```bash\n# See the Help and options for the Quickstart Template\ndotnet new prismforms -h\n\n#Create your first quickstart\nmkdir Contoso.AwesomeApp\ncd Contoso.AwesomeApp\ndotnet new prismforms -id com.contoso.awesomeapp -fr netstandard1.6 -mc -ios-secret\n     \"{your ios secret}\" -android-secret \"{your android secret}\" -data AzureMobileClient\n     -auth AADB2C -client-id \"{your AADB2C application id}\"\n#Be sure the B2CName in secrets.json matches your AAD B2C name\n```","date_published":"2017-07-16T07:44:00.000Z","date_modified":"2017-08-05T13:02:59.000Z","tags":[".NET","Prism","Xamarin","Xamarin Forms","C#","MVVM"]},{"id":"https://dansiegel.net/post/2017/05/30/why-you-aren-t-attracting-or-keeping-top-talent","url":"https://dansiegel.net/post/2017/05/30/why-you-aren-t-attracting-or-keeping-top-talent","title":"Why you aren't attracting or keeping Top Talent","summary":"I'm personally contacted by anywhere from 5-20 recruiters a week, and honestly well over 90% of the job \"opportunities\" do nothing more than make me laugh so...","content_text":"I'm personally contacted by anywhere from 5-20 recruiters a week, and honestly well over 90% of the job \"opportunities\" do nothing more than make me laugh so hard, milk would squirt out of my nose (if I was drinking milk). The reality of it is, that it doesn't much matter whether you're looking for C2C, W2, or 1099, the top talent out there is laughing your offers all the way to trash (much more often than you think). Thanks to the digital world, they didn't even get the satisfaction of crumpling it up and realizing why they're in IT and not the NBA.\n\n## What Is Top Talent\n\nWhat is top talent anyway? While we can get into a debate on how to define \"Top Talent\", I would generically define top talent as someone who possesses the following qualities:\n\n-   They have the all or most of the expertise that you need today, and can quickly pick up any missing pieces.\n-   They have a drive to always be learning. This ensures that they always be able to handle your needs as needs evolve through an ever changing world.\n-   They appear to be a workaholic to most people, because they love what they do.\n\n## Why Top Talent Ignores Offers\n\nSo why then does Top Talent ignore so many offers? Well for starters you need to understand who you're dealing with. I was recently reading a great post from Scott Hanselman on the topic of '[Attending Your First Conference](https://www.hanselman.com/blog/SuggestionsAndTipsForAttendingYourFirstTechConference.aspx)'. In his post he posted a number of helpful pointers from the community on Twitter. While the topic itself has nothing to do with your hiring Top Talent, it does expose a reality in the IT world as a whole. The reality is most people in IT, and especially programmers are Introverts. It's not that you can't put us in a room and expect us to have a conversation with anyone at all, but most of us probably prefer not to.\n\n> _Our company culture is important to us, and we would lose that if employees weren't in the office._\n\nNow I've heard a number of CEO's and other managers discuss reasons why they insist on their staff being on site. I will admit that in certain cases I even see valid arguments for having at least some of your staff in close enough proximity that they could come into the office for an emergency, or on some sort of periodic basis like for Monday meetings or on a rotating schedule with other programmers. The reality of it though, is that if your answer is something like the more common reasons I hear, you're losing out on the top talent when you don't need to.\n\n> _We insist that our employees work from the office to promote a better sense of communication and collaboration._\n\nThe On-Prem verses Remote really touches a couple of issues. Of course it goes back to the natural state of most programmers to be introverts, but it really goes deeper than that. In the event that I live a half an hour away from the office, \"Rush Hour\" makes that at least an hour unless there was an accident and it suddenly takes two hours. So now you are asking a workaholic to devote an extra 2-3 hours of their day to showing their face, they didn't want to show in the first place, on an 8 hour day that was probably closer to 10-12 hours. They've now lost a chance to have a life and will likely burn out and leave. \n\n> _When we find the right talent, we'll pay relocate them even if we have to move them cross country (or help them get a Visa)._\n\nSo your 'On-Prem' mentality just prevented you from hiring the Introverts, and the candidate might have said yes is burning out. That still doesn't cover it all though. The next thing you have to look at is the candidate pool. You might be based in the Bay Area or New York City and think I'm in this super Urban area with tons of programmers. Nothing says that the right person for your company is located where you are. Besides with a lot of specialties it's easy to quickly end up looking for a Unicorn. Honestly this is probably the quickest way to get ignored by Top Talent. Let's just be honest most of us care about our friends and our family. We probably have roots where we are and we don't feel like being uprooted from our lives, or uprooting the lives of our spouse and kids because you read some mantra about \"Company Culture\".\n\n## Attracting (and KEEPING) Top Talent\n\nIf you want to attract the Top Talent you need to spend some time taking inventory. You might be surprised what you find. If you take the time to address the following issues, the Top Talent out there will take notice.\n\n-   Don't Freak Out! Take an inventory of what your current company culture is. Chances are your open floor plan with your programmers is still quiet like a library with only the sound of the keyboards as your programmers are chatting via Slack or Skype for Business. All that's left is to let them work remotely.\n-   Offer Top Talent the ability to work Remotely even when it means you need to fly them into the office periodically for meetings or corporate events.\n-   Be prepared to pay for Top Talent, but don't focus on Salary. Nobody likes being asked how much they expect. The reality is they want to tell you $1,000,000, but figure you'll only pay $120,000. You wish you could legally pay them $10,000, but you are prepared to pay $140,000. Another company offers them $135,000 and they're out the door. The truth is while there might still be some negotiation on salary, this classic paradigm is from a culture that no longer exists. Be prepared to tell them upfront what you are prepared to do. If what you're thinking is too low they'll tell you. \n-   Benefits matter. The simple fact is if you offer $120,000 base salary and another company offers $130,000 base that doesn't mean Top Talent is automatically going for the higher base. \n    -   Health Insurance: Think about what you offer. You'd be surprised at how many recruiters and HR Managers I've talked to couldn't answer questions like \"Do you offer a PPO or HMO\". Another huge point, does the company bear the full cost of the insurance or is it a shared expense with the employee? That could make all the difference in the world.\n    -   Tuition reimbursement. Just because you're looking for Top Talent, doesn't mean that they don't have student loans. If your company is willing to help them pay it off, don't be shy.\n    -   PTO: If you start your employees off with 4 weeks of PTO instead of the classic 2 weeks, seriously rethink your job posting that just says benefits include \"PTO\". Chances are Top Talent will take a pay cut just for the ability to spend time doing what they love with the people they love.\n-   If you expect some Loyalty, be prepared to reciprocate and have some examples of how the Company values Loyalty to it's employees, contractors and consultants. \n-   Show you care as much about continuing education as they do. Don't wait for them to ask/beg, offer to pay for their time and all expenses for them to attend at least one or two conferences each year. \n-   Show you care about Quality of Life. \n    -   Provide ample PTO without a hassle. One of my favorites came from a company that insists their developers take a week paid vacation every 12 weeks.\n    -   Be flexible. Every company has meetings, but provide enough work day flexibility that they can split their day up. This could mean they have the time to make their kid's soccer game, or simply that they got to clear their mind and go for a walk or a bike ride for a couple of hours. \n-   Be open, and be serious about improving. If the Top Talent candidate were to ask their prospective coworkers about working with your company, what would they say? Would they say you have an Open Door/Inbox policy? Would they say they can speak candidly to you without fear of reprisal? Do you seek feedback?\n\n## Working with Contractors and Consultants\n\nI know you may be thinking I started off by saying it doesn't matter whether you're looking at C2C, W2, or 1099, but so far it seems like I've only talked about W2. The sad reality is that even for 1099/C2C a surprising amount of companies think that Consultants and Contracts are employees they don't pay benefits to. Everyone of course is different, but you might be surprised when you rethink how you approach contractors and consultants. If a contractor is going to charge you $100+/hr chances are you do not want to think about overtime. The problem is that you have a contract that is going to last 6 or 12 months. \n\nJust because you're working with a contractor doesn't mean that they don't care about the same things that your employees do. In fact for contractors it is even more critical that they have things like remote work flexible schedules. Let's be honest if you hired a contractor even when it's \"Temp to Hire\" you started off the relationship by saying you have no loyalty to them whatsoever. If they can't maintain an ability to attract other clients to sustain them at the end of their contract with you, they are charging you more, even if they don't tell you that. \n\nAs sad as it is, companies so often suffer because they didn't think about the needs of the contractor. When you approach a contractor from a basis that you will pay a flat negotiated rate, and that they don't need to worry about being paid, even when they took the week to go on vacation or go to a seminar somewhere, you might be surprised at how much more you get from that contractor. Suddenly you'll have unleashed the contractor to burn the midnight oil to get things done for you, while ensuring that they can make the appropriate decisions they need to in order to put the best foot forward.","date_published":"2017-05-30T04:06:00.000Z","date_modified":"2017-05-30T13:48:51.000Z","tags":["developers","recruiting"]},{"id":"https://dansiegel.net/post/2017/05/23/azure-mobile-client-helpers","url":"https://dansiegel.net/post/2017/05/23/azure-mobile-client-helpers","title":"Azure Mobile Client Helpers","summary":"To be honest, I forget now exactly when I first heard about the Azure Mobile Client library. I do however remember an initial sense of excitement for being able...","content_text":"To be honest, I forget now exactly when I first heard about the Azure Mobile Client library. I do however remember an initial sense of excitement for being able to add Online/Offline syncing to my apps. That excitement gradually faded a little when I started to deep dive into the library and realized that every project I wanted to use the Azure Mobile Client, meant that there were a number of helpers I would need to recreate. If you're familiar with the Azure Mobile Client, the chances are you may have seen tutorial either by or inspired by Adrian Hall's [guide](https://adrianhall.github.io/develop-mobile-apps-with-csharp-and-azure/). Even Xamarin's \"Connect App\" template uses this basic approach. Honestly I don't mind providing an implementation for an interface or two in my projects, but it gets a little old when I have to redevelop everything in my projects.\n\nIt was for this reason that I decided to wrap the abstractions and some basic implementations into a reusable library. The [AzureMobileClient.Helpers](https://github.com/dansiegel/AzureMobileClient.Helpers) library wraps what you need to quickly get off the ground running with the AzureMobileClient. But it's really about more than simply providing the base classes you need to be successful. It's also about helping you to develop the code that follows best practices, and helps keep your code testable. \n\nSo what does getting started even look like? Well let's say we have the classic `TodoItem`.\n\n```csharp\npublic class TodoItem : EntityData\n{\n    public string Name { get; set; }\n    public string Notes { get; set; }\n    public bool Done { get; set; }\n}\n```\n\nWe don't need to define any of the fields specific to our Azure Mobile Services Entity as it's already defined in the `EntityData` base class. Since I'm all about Developer Experiences, and trying to make things to where we have to write as little code as possible to have a fantastic app, I'll use Mobile Center to quickly setup a Mobile Backend. \n\n![Create an Easy Table](/images/blog/azure-mobile-client-helpers/01-image.webp)\n\nNavigate to the Tables tab and create your first table. Note that when you first go to the Tables tab you'll be asked to link the app to your Azure account. The Mobile Center will automatically go out and provision a new Mobile App Service and setup everything in a Resource Group for your app. You should be aware that you can go into the Azure Portal at any time to manage the resource. When Mobile Center sets everything up it will use a SQLite database which is great for testing, and not so great for Production. If you want to set this up to be more than a demo, before you create your first table go into the Azure Portal and configure either a SQL Server connection or Storage connection under `Mobile -> Data Connections`. For this example we're not going to set up any authentication, but you can do this easily from Mobile Center. The great thing about Easy Tables is that the data store allows for a dynamic schema so all we need to provide for this is a table name and click Create.\n\n![Set the table name](/images/blog/azure-mobile-client-helpers/02-image.webp)\n\nReally with very little effort and Zero code on your part, your mobile backend is ready. Notice I said it's 'Zero code on your part', and not 'Zero code'. Behind the scenes it is setting up a Node.js backend adding the files you need. You can go into the `App Service Editor` at any time and make manual changes if you need to. All you need to do now is setup your Xamarin application. Keeping things simple let's set up the application using Prism with a NetStandard1.4 Core library so that we can use the latest NetStandard release of the Azure Mobile Client and the Helpers library I mentioned before.\n\nNow in order to keep things a little easier I want to keep a singular app context that I can use so I can easily scale from 1:N models without having to update the dependencies I'm injecting into my ViewModels. To do this I'm going to reference the Container specific implementation for the library so I can more easily set this up. For this we'll use the DryIocCloudAppContext and provide our Tables very much like we would using Entity Framework and the DbContext.\n\n```csharp\npublic class AwesomeAppContext : DryIocCloudAppContext\n{\n    public AwesomeAppContext(IContainer container)\n        : base(container, AppSettings.DbName)\n    {\n    }\n\n    // NOTE: This must be here for the AppContext to pick up your Model Type\n    // and ensure that the table is created in the SQLite store\n    ICloudSyncTable<TodoItem> TodoItems => SyncTable<TodoItem>();\n}\n```\n\nNow, we just need to register our services:\n\n```csharp\nprotected override void RegisterTypes()\n{\n    Container.Register(typeof(ICloudSyncTable<>), typeof(AzureCloudSyncTable<>), reuse: Reuse.Singleton);\n    Container.RegisterInstance<IMobileServiceClient>(new MobileServiceClient(AppSettings.BackendUri));\n    Container.Register<AwesomeAppContext>(Reuse.Singleton);\n\n    Container.RegisterTypeForNavigation<NavigationPage>();\n    Container.RegisterTypeForNavigation<MainPage>();\n    Container.RegisterTypeForNavigation<TodoItemDetailPage>();\n}\n```\n\nWith our services we're all set. We just need to add `AwesomeAppContext` to the constructor of our ViewModel and we can access our data. \n\n```csharp\npublic class MainPageViewModel : BaseViewModel, INavigatedAware\n{\n    private AwesomeAppContext _context { get; }\n\n    public MainPageViewModel(AwesomeAppContext context)\n    {\n        _context = context;\n        TodoItems = new ObservableRangeCollection<TodoItem>();\n    }\n\n    public ObservableRangeCollection<TodoItem> TodoItems { get; }\n\n    public async void OnNavigatedTo(NavigationParameters parameters)\n    {\n        await _context.TodoItems.SyncAsync();\n        TodoItems.ReplaceRange(await _context.TodoItems.ReadAllItemsAsync());\n    }\n}\n```\n\nFinally we can go from idea to working app in under 10 minutes with full Online/Offline Sync. You can see the full working TodoDemo app on [GitHub](https://github.com/dansiegel/TodoDemo).","date_published":"2017-05-23T03:00:00.000Z","date_modified":"2017-08-05T13:04:50.000Z","tags":["Prism","Xamarin","Azure","Dependency Injection","Xamarin Forms","Mobile Center"]},{"id":"https://dansiegel.net/post/2017/05/12/xamarin-package-authoring","url":"https://dansiegel.net/post/2017/05/12/xamarin-package-authoring","title":"Xamarin Package Authoring","summary":"Whether you're just a .NET developer or a Xamarin developer we've all used NuGet. Chances are if you're anything like me, you may have started down the...","content_text":"Whether you're just a .NET developer or a Xamarin developer we've all used NuGet. Chances are if you're anything like me, you may have started down the development path on some project and developed out some really awesome tools to help you. Then maybe you were in a fancy design meeting. Maybe you were busy thinking how Rome didn't become a great Empire by having meetings... \n\n![Rome didn't have meetings](/images/blog/xamarin-package-authoring/01-image.webp)\n\nPerhaps you're more like me and you were either at Starbucks or on your way to Starbucks, and a great idea struck. Then you realized that all of the functionality you need you just implemented on this other project. Obviously the answer is to decouple the code you wrote from your last project and put it into it's own project. The problem you ran into though is that you develop on a Mac and NuGet is for PC right?\n\nNow I could go into authoring packages with the new `csproj` format using `dotnet pack`. But truthfully that is a topic all by itself. It's actually something that many developers may not realize you can do. I mean if you go to NuGet.org all you can find is the download for the Windows exe. What people may not realize though is that it's much easier to start authoring packages using the Xamarin toolset than you may realize.\n\nWhen you installed Xamarin Studio or the newly released Visual Studio for Mac along with the IDE and tooling for Android & iOS development, you actually got Mono. Now if you go to Google and search for Mono because you have no clue what I'm talking about, don't worry, we're not talking about the infectious disease. If you go down under WebMD to the Mono Project you'll see what we're talking about. Bundled in Mono is NuGet and even better the executable is already added to your path so once you open the terminal you can just execute NuGet commands. Now there is one caveat, and it is an important one. Mono for some unknown reason refuses to update the bundled version from 2.12 so you're good if you want to query a NuGet feed or pull a package, but that's pretty much it. Fear not though, you just need to run `sudo nuget update -self`, and it will update to the latest version the same as if you ran it on Windows. \n\nThere are of course some gotcha's here:\n\n1.  If you're building platform specific code that includes the full net framework like net45 you're going to have to build the source on Windows. That said if you built it on your PC but maybe had the project in your DropBox then you can pack the Windows built binary on the Mac\n2.  Xamarin Studio/Visual Studio for Mac updates. The updates typically include an Update for Mono which will reset your NuGet version back to 2.12 unless they ever decide to update the bundled version so after running updates on the IDE you will need to update NuGet before packing your projects.","date_published":"2017-05-12T05:55:00.000Z","date_modified":"2017-05-12T15:56:27.000Z","tags":["Xamarin","NuGet","Mono",".NET","Mac"]},{"id":"https://dansiegel.net/post/2017/04/07/a-dot-net-developer-on-a-mac","url":"https://dansiegel.net/post/2017/04/07/a-dot-net-developer-on-a-mac","title":"A Dot Net Developer on a Mac","summary":"Recently I had a chance to attend a meetup here in San Diego. To be honest, around other developers I sometimes feel like the odd man out. I mean here I am a C#...","content_text":"Recently I had a chance to attend a meetup here in San Diego. To be honest, around other developers I sometimes feel like the odd man out. I mean here I am a C# Dot Net developer, and I'm showing up to code with a Mac. It really wasn't all that long ago that you might look at a \"C# Developer\" doing something like that, as if they were on crack. But the times they are changing. In fact, at that meetup the odd man out, was the dev with a Windows Laptop.\n\n  \n\nI often have conflicting feelings about my development. On the one hand, I absolutely LOVE Visual Studio. As far as I'm concerned it hands down beats every other IDE out there. As I mentioned though, when I'm on the go, more often than not I'm working off my Mac. So then how on earth does a Dot Net developer work on a Mac. Well truthfully if it wasn't for all of the hard work coming from Microsoft the past few years I'm not sure it would be anywhere near as pleasant as it is now.\n\n  \n\nI realize that there are still a lot of short comings with NetStandard, for one it is completely useless for Xamarin libraries that contain XAML files. That said the work that has been done around the NetStandard has been instrumental in making Dot Net even a citizen in non-Windows environments. Part of the problem with being a Dot Net developer outside of Windows is that the tooling was heavily integrated with Windows, so it wasn't as easy as install Mono... go...\n\n  \n\nI have been gleefully watching over the past couple of years as all of that has started to change. One of my recurring issues, and frankly one that may have caused me to pull out a lot of hair, was that Microsoft kept increasing the developer experience around PowerShell. Well that's cool, but everyone else in the world is using Bash and PowerShell wasn't available outside of Windows. So to me I kept asking how stupid can you be to increase the dependency on a Windows Environment? Well truth be told they were working on porting [PowerShell](https://github.com/PowerShell/PowerShell) and it is actually available for Mac and Linux now so any PowerShell commands I may have been running in the past on PC, are now available on Mac.\n\n  \n\nBut it really doesn't end with PowerShell. For the past year I have been somewhat vocal about what they call \"Visual Studio for Mac\", or as I call it \"Xamarin Studio with a Visual Studio logo\". This week the team released `Preview 6` for VS for Mac. For the first time Mac users like myself are getting a lot closer to some of the critical pieces that have been missing. Now you may have noticed that until now, I haven't mentioned Visual Studio Code. It's not a bad editor, in fact I use it when writing articles for this blog. It's a great environment as well for quickly working up an AspNetCore website and running it locally. But it's been a little frustrating as a Dot Net developer that there hasn't been any tooling (other than PowerShell) that would allow me to connect to Azure and deploy resources right from the IDE. [Preview 6](https://developer.xamarin.com/releases/vs-mac/preview/vs-mac-preview1/#Changes_in_Preview_6) really changes things though. First it brings tooling directly into the IDE to deploy an AspNetCore application straight to Azure whether to an existing resource or a new resource you want to create. The next piece of critical functionality of course... C# 7. It may have taken a month longer, but it's finally available on Mac, proof they really are using the same Rosyln as Visual Studio???","date_published":"2017-04-07T12:32:00.000Z","date_modified":"2017-05-09T19:48:43.000Z","tags":[".NET","Xamarin","Xamarin Forms","C#"]},{"id":"https://dansiegel.net/post/2017/04/01/the-hamburger-menu-with-prism-forms","url":"https://dansiegel.net/post/2017/04/01/the-hamburger-menu-with-prism-forms","title":"The Hamburger Menu with Prism Forms","summary":"How many times have you heard someone ask about a Hamburger menu in Xamarin Forms? It's a topic that comes up fairly frequently and it seems there are two...","content_text":"How many times have you heard someone ask about a Hamburger menu in Xamarin Forms? It's a topic that comes up fairly frequently and it seems there are two distinct camps. Those who will tell you it's drop dead simple, and those who are stuck trying to figure out why if it's so simple, they can't figure it out. Honestly there are already a ton of YouTube videos and Blog Posts on the topic, so much so that I didn't want to touch the subject. However there is still a ton of confusion about the \"Secret Sauce\".\n\nI would like to think the reality is somewhere in between. So often I find the major reason for these types of disagreement, has more to do with mis-managed expectations. For those stuck trying to figure out how to implement the Hamburger Menu, I think there are two key \"gotcha's\".\n\nI've seen a number of blogs on the topic, but it seems like they're quick to say just use a `MasterDetailPage`. Ok you're done, you don't have to go home, but don't stay here. But that isn't the whole story. I've seen some blogs that do make more of a point to tell you that your Detail Page must be wrapped in a `NavigationPage`. But again, that just isn't the whole story.\n\nSo how on earth do you get that hamburger menu? Well for starters, you don't go to McDonalds (or for those in my neck of the woods, In N Out). When people ask about the \"hamburger menu\" they aren't asking how do you implement a slide out menu in your app. But that's what we keep telling people. In order to get the \"hamburger menu\", you need images. See people kept telling you it was easy. The secret sauce is to add an Icon to the `Master` page of the `MasterDetailPage`. Xamarin actually does this in their sample, but seems to gloss over the importance.\n\nSince I'm a Prism guy though, let me go over the creation of a Prism App with a Hamburger Menu. I will assume you have the basic Prism App setup.\n\nApp.xaml.cs\n\n```csharp\npublic partial class App : PrismApplication\n{\n    public App( IPlatformInitializer initializer = null )\n        : base( initializer )\n    {\n\n    }\n\n    protected override void OnInitialized()\n    {\n        InitializeComponent():\n        NavigationService.NavigateAsync(\"MainPage/NavigationPage/ViewA\");\n    }\n\n    protected override void RegisterTypes()\n    {\n        Container.RegisterTypeForNavigation<NavigationPage>();\n        Container.RegisterTypeForNavigation<MainPage>();\n        Container.RegisterTypeForNavigation<ViewA>();\n        // So on and so forth...\n    }\n}\n```\n\nYou'll notice here that there are three View's I'm registering. The first is just simply the Xamarin Forms NavigationPage. There's no magic here. The next is my MainPage, which I will go more into detail. And lastly I register ViewA which is just some View that I will have as a Detail Page.\n\n  \n\nMainPage.xaml\n\n```xml\n<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<MasterDetailPage\n    xmlns=\"http://xamarin.com/schemas/2014/forms\"\n    xmlns:x=\"http://schemas.microsoft.com/winfx/2009/xaml\"\n    x:Class=\"HamburgerMenu.Views.MainPage\">\n    <MasterDetailPage.Master>\n        <!-- Hamburger Menu Secret Sauce... Add an Icon!!!! Make sure it's in your resources for your Platform Project -->\n        <NavigationPage Title=\"Required Foo\" Icon=\"hamburger.png\">\n            <x:Arguments>\n                <ContentPage Title=\"Menu\">\n                    <StackLayout Padding=\"40\">\n                        <Label Text=\"{Binding UserName,StringFormat='Hello, {0}'}\" />\n                        <Button Text=\"View A\" Command=\"{Binding NavigateCommand}\" CommandParameter=\"Navigation/ViewA?message=Did%20you%20see%20the%20secret%20sauce%3F\" />\n                        <Button Text=\"View B\" Command=\"{Binding NavigateCommand}\" CommandParameter=\"Navigation/ViewB?message=Told%20you%20Prism%20Rocks%21%21%21\" />\n                        <Button Text=\"View C\" Command=\"{Binding NavigateCommand}\" CommandParameter=\"Navigation/ViewC?message=Does%20the%20hamburger%20make%20you%20hungry%3F%3F%3F\" />\n                    </StackLayout>\n                </ContentPage>\n            </x:Arguments>\n        </NavigationPage>\n    </MasterDetailPage.Master>\n</MasterDetailPage>\n```\n\nAll code means stuff, and there's a bit going on. Whether I'm coding or not, I'm generally a very light hearted kind of guy that likes to joke around. So you'll notice here the Navigation Page that I have as the `MasterDetailPage.Master`, has a title of \"Required Foo\". That is because Title is a required field for the Master, while the Icon is optional. The icon when supplied hides the title. I mentioned that a `NavigationPage` is a requirement for the \"Hamburger Menu\", but that is for the Detail, NOT the Master. I am choosing to use the NavigationPage in my Master in this sample, not because I expect actual navigation within the 'Menu', but rather because it quickly gives me the ability to add a nice Header and Toolbar Menu Items.\n\n  \n\nNow before you go all crazy trying to figure it out. You can download this [zip](/downloads/Hamburger.zip) for the Hamburger Icon assets for Android and iOS.","date_published":"2017-04-01T13:00:00.000Z","date_modified":"2017-05-09T19:48:25.000Z","tags":["Prism","Xamarin","Xamarin Forms","C#","XAML"]},{"id":"https://dansiegel.net/post/2017/03/31/prism-forms-6-3-0-highlights","url":"https://dansiegel.net/post/2017/03/31/prism-forms-6-3-0-highlights","title":"Prism Forms 6.3.0 Highlights","summary":"For those following Prism 6.3, it's been a while coming, but there is a lot there. Here are a few helpful things to get you going. Behaviors One of my favorite...","content_text":"For those following Prism 6.3, it's been a while coming, but there is a lot there. Here are a few helpful things to get you going.\n\n## Behaviors\n\nOne of my favorite additions to Prism Forms 6.3.0 is the addition of Behaviors. First of all Prism gives you a great `BehaviorBase<T>` class you can use for all of your custom behaviors. But we finally have an `EventToCommandBehavior` that allows us to execute our ViewModel Commands when an event is triggered, and the control doesn't directly support Commands for that event. This is great for things like attaching to something like a `ListView` where we might want to work with the `ItemTapped` or `ItemSelected` events. You have a wide degree of flexibility here where you can choose to directly accept the EventArgs in your command or you can use a custom converter to grab the item from the EventArgs.\n\n## NavigationParameters\n\nOne of the breaking API changes you may notice is with the NavigationParameters. In the past, the NavigationParameters was based on a Dictionary which gave us the limitation that a key could only be used once in the querystring. While most of the time this was fine, there are so many cases where you just need to pass a list of something. Along with the new implementation are some great helpers including both a `GetValue<T>` and `GetValues<T>`. These are also safe to use if the key didn't actually exist so there's no more need for `if( parameters.ContainsKey(\"foobar\")) FooBar = (Foo)parameters[\"foobar\"]`. Naturally you will get a default value, so do check for \\`null\\`.\n\n## INavigationAware\n\nProbably one of the most used interfaces in my Prism Forms apps, is INavigationAware. This is a major breaking change. That said, it's worth the frustration of the breaking change here. First of all `INavigationAware` is no longer a standalone interface. It is now actually the combination of two concepts `INavigatingAware` and `INavigatedAware`. As the verbs imply, one is based on Navigation that is about to occur, while the other is about Navigation that has occurred. One of the complaints I often heard, and frankly had myself was that with `OnNavigatedTo`, there was a visible UI update as my ViewModel was updating the Values that were bound on the UI. `INavigatingAware` with it's singular `OnNavigatingTo` really helps to address this problem.\n\nThe reason why we were seeing the UI changes was that the ViewModel never had a chance to load before we pushed the page onto the Navigation Stack. `OnNavigatingTo` is only called once, and only before we actually push the page to the stack. Like the sample below shows, we may have some default value that is really only there to alert the developer of a problem or is there for the design time. With the `OnNavigatingTo`, this value will no longer appear when the the page is actually pushed as the value of `Message` will update to whatever was in the NavigationParameters.\n\n```csharp\npublic class FooBarViewModel : BindableBase, INavigatingAware\n{\n\tprivate INavigationService _navigationService { get; }\n\n\tpublic FooBarViewModel( INavigationService navigationService )\n\t{\n\t\t_navigationService = navigationService;\n\t}\n\n\tprivate string _message = \"some default value\"\n\tpublic string Message\n\t{\n\t\tget { return _message; }\n\t\tset { SetProperty( ref _message, value ); }\n\t}\n\n\tpublic void OnNavigatingTo( NavigationParameters parameters )\n\t{\n\t\tMessage = parameters.GetValue<string>( \"message\" );\n\t}\n}\n```\n\n## BindableBase Update\n\nSo this one got snuck in last minute. `BindableBase` now allows you to specify an action when the value is changed. Also changed was the change up to call `RaisePropertyChanged` when a property has been changed. This becomes highly useful in a variety of situations like the with the following:\n\n```csharp\npublic class Person : BindableBase\n{\n    private string _firstName;\n    public string FirstName\n    {\n        get { return _firstName; }\n        set { SetProperty( ref _firstName, value, () => RaisePropertyChanged( nameof( Name ) ) ); }\n    }\n\n    private string _lastName;\n    public string LastName\n    {\n        get { return _lastName; }\n        set { SetProperty( ref _lastName, value, () => RaisePropertyChanged( nameof( Name ) ) ); }\n    }\n\n    public string Name => $\"{FirstName} {LastName}\";\n}\n```\n\n## IActiveAware\n\nFor long time Prism users, `IActiveAware` is nothing new. In fact it's been there the whole time. But for Prism Forms, it's really been useless until 6.3.0. With the addition of behaviors, 6.3.0 adds a new behavior to help with one of the major problems that we have when using any MultiPage such as a TabbedPage or CarouselPage in our application. That problem of course, how on earth do you figure out when the user is actually on your page. How to handle the Children of a MultiPage is something that we will be seeing some additional work on before the next release. But in the mean time the `IActiveAware` behavior really gives us a great tool. Going forward with 6.3.0, I expect we will see a lot of developers adopting a pattern of making ViewModels for children of TabbedPages like the following:\n\n```csharp\npublic class TabbedChildPageAViewModel : BindableBase, INavigationAware, IActiveAware\n{\n\tprivate bool isInitialized = false;\n\n\tpublic event EventHandler IsActiveChanged;\n\n    private bool _isActive;\n\tpublic bool IsActive\n    {\n        get { return _isActive; }\n        set { SetProperty( ref _isActive, value, OnIsActiveChanged ); }\n    }\n\n\tpublic void OnNavigatingTo( NavigationParameters parameters )\n\t{\n\t\tif( isInitialized ) return;\n\t\tisInitialized = true;\n\n\t\t// Implement loading logic here\n\t}\n\n    private void OnIsActiveChanged()\n    {\n        // Do Foo\n    }\n}\n```\n\nwith a TabbedPage like the following:\n\n```csharp\npublic partial class MyTabbedPage : TabbedPage, INavigatingAware\n{\n\tpublic MyTabbedPage()\n    {\n        InitializeComponent();\n    }\n\n    public void OnNavigatingTo( NavigationParameters parameters )\n    {\n        foreach( var child in Children )\n        {\n            // You only need to do this on the child if any of your child pages actually implement this.\n            ( child as INavigatingAware )?.OnNavigatingTo( parameters );\n            ( child?.BindingContext as INavigatingAware )?.OnNavigatingTo( parameters );\n        }\n    }\n}\n```\n\nWith this strategy you can now both initialize your Tabbed Page Children, and handle the Activation/Deactivation events that occur when the user changes the tab. You can check out a complete example of this in the [Prism Samples](https://github.com/PrismLibrary/Prism-Samples-Forms).","date_published":"2017-03-31T01:47:00.000Z","date_modified":"2017-05-09T19:48:08.000Z","tags":[".NET","Prism","Xamarin","Xamarin Forms","C#"]},{"id":"https://dansiegel.net/post/2017/03/16/writing-cleaner-more-concise-code-with-fody","url":"https://dansiegel.net/post/2017/03/16/writing-cleaner-more-concise-code-with-fody","title":"Writing Cleaner, More Concise Code with Fody","summary":"We've all written code that we looked at and said, \"Wow this sucks\". It's not necessarily that the code itself sucks, but perhaps we just have to make the code...","content_text":"We've all written code that we looked at and said, \"Wow this sucks\". It's not necessarily that the code itself sucks, but perhaps we just have to make the code very verbose, and we wish there was some way we could clean it up. Just as an example I'll pick on `INotifyPropertyChanged`. Chances are if you work with an MVVM framework like Prism or MvvmCross, you're pretty used to this. I am a huge fan of simple, elegant, and self documenting code. The problem with `INotifyPropertyChanged`, is that while it's necessary, it also bloats our code, and can quickly make it a little harder to see what our real intent is.\n\n```csharp\n// The standard format for a Prism ViewModel\npublic class MyPageViewModel : BindableBase\n{\n    private string _email;\n    public string Email\n    {\n        get { return _email; }\n        set\n        {\n            if( SetProperty( ref _email, value ) )\n            {\n                OnEmailChanged();\n            }\n        }\n    }\n\n    private bool _isValid;\n    public bool IsValid\n    {\n        get { return _isValid; }\n        set { SetProperty( ref _isValid, value ); }\n    }\n\n    public void OnEmailChanged()\n    {\n        IsValid = RegEx.IsMatch( Email, AppSettings.EmailRegExPattern );\n    }\n}\n```\n\nNow it's great that so many framework's give us some sort of base class we can inherit from that already implements `INotifyPropertyChanged` so we at least don't have to do that, but let's be honest our real intent is more like:\n\n```csharp\n// First possible refactoring\npublic class MyPageViewModel\n{\n    public string Email { get; set; }\n\n    public bool IsValid { get; set; }\n\n    public void OnEmailChanged()\n    {\n        IsValid = RegEx.IsMatch( Email, AppSettings.EmailRegExPattern );\n    }\n}\n```\n\nOr even simpler like:\n\n```csharp\n// Second possible refactoring\npublic class MyPageViewModel\n{\n    public string Email { get; set; }\n\n    public bool IsValid\n    {\n        get { return RegEx.IsMatch( Email, AppSettings.EmailRegExPattern ); }\n    }\n}\n```\n\nThe question you may have, is how can you get your code simplified like the last two examples? This is where it's important to take a moment, and look at one of those things, that most of us developers do not like to think about. Let's be honest, it's something that to most of us, is easier to consider \"Magic\". Often we just think about the code we write, and then it ends up a compiled library or executable. The thing is, there is all sorts of stuff we can do during compilation to manipulate our code. [Fody](https://github.com/Fody/Fody) offers some excellent tooling to do exactly this, and with their [PropertyChanged library](https://github.com/Fody/PropertyChanged) you can easily add `INotifyPropertyChanged`.\n\n  \n\nAfter installing the library, your ViewModel simply needs to add a single attribute and `INotifyPropertyChanged` will be 'Weaved' in.\n\n```csharp\n[InjectPropertyChanged]\npublic class MyPageViewModel\n{\n    // ViewModel implementation\n}\n```\n\nGiven the above examples of what we might like to do, the generated class would look like the following:\n\n```csharp\n// First refactoring generated output\npublic class MyPageViewModel : INotifyPropertyChanged\n{\n    string email;\n    public string Email\n    {\n        get { return email; }\n        set\n        {\n            if( email != value )\n            {\n                email = value;\n                OnEmailChanged();\n                OnPropertyChanged( \"Email\" );\n            }\n        }\n    }\n\n    bool isValid;\n    public bool IsValid\n    {\n        get { return isValid; }\n        set\n        {\n            if( isValid != value )\n            {\n                isValue = value;\n                OnPropertyChanged( \"IsValid\" );\n            }\n        }\n    }\n\n    public virtual void OnEmailChanged()\n    {\n        IsValid = RegEx.IsMatch( Email, AppSettings.EmailRegExPattern );\n    }\n\n    public event PropertyChangedEventHandler PropertyChanged;\n\n    public virtual void OnPropertyChanged(string propertyName)\n    {\n        var propertyChanged = PropertyChanged;\n        if (propertyChanged != null)\n        {\n            propertyChanged(this, new PropertyChangedEventArgs(propertyName));\n        }\n    }\n}\n```\n\nOr the second preferred example:\n\n```csharp\n// Second refactoring generated output\npublic class MyPageViewModel : INotifyPropertyChanged\n{\n    string email;\n    public string Email\n    {\n        get { return email; }\n        set\n        {\n            if( email != value )\n            {\n                email = value;\n                OnPropertyChanged( \"Email\" );\n                OnPropertyChanged( \"IsValid\" );\n            }\n        }\n    }\n\n    public bool IsValid\n    {\n        get { return RegEx.IsMatch( Email, AppSettings.EmailRegExPattern ); }\n    }\n\n    public event PropertyChangedEventHandler PropertyChanged;\n\n    public virtual void OnPropertyChanged(string propertyName)\n    {\n        var propertyChanged = PropertyChanged;\n        if (propertyChanged != null)\n        {\n            propertyChanged(this, new PropertyChangedEventArgs(propertyName));\n        }\n    }\n}\n```\n\nYou may notice a couple of key differences here, and they will have an impact on our application. The differences can be extremely subtle. In the first example we execute an action when our `Email` property is updated. In the second we have no action executed but we call `OnPropertyChanged` for the `IsValid` property anytime the `Email` property is updated. What does all of this mean?\n\n  \n\nI fully admit I really like the syntax of the second refactoring, it is far more elegant. That said, there is a particular problem that we would face using this syntax. Take the email `john.doe@gmail.com`, and say that the Email field is bound to an Entry field. When the user types 'j' `OnPropertyChanged` is called for the `Email` property and `IsValid` property. The user types 'o', again `OnPropertyChanged` is called for both properties. This would continue for every single character meaning that the UI would have to respond to the event for both bindings.\n\n  \n\nNow say that you use the first implementation where you call the action `OnEmailChanged` when the `Email` property is changed, and this then executes `IsValid = RegEx.IsMatch( Email, AppSettings.EmailRegExPattern )`. What we are really doing is checking to see if anything has really changed. Again saying that the user types 'j', the action attempts to set a value of 'false' for `IsValid`. Since the property already was false, `OnPropertyChanged` is never called and the UI never has to respond to it. In fact the user would have to have entered `john.doe@gmail.co` before we would see `OnPropertyChanged` being executed for the `IsValid` property. Another way of putting it that we would have been telling the UI to do something 17 times, taking up CPU time that was never needed. Then we would notify the UI again when the user typed the final character.\n\n  \n\nBy using a helper like Fody, we can instead write clean concise code, following the best coding practice that fits our exact situation.","date_published":"2017-03-16T04:35:00.000Z","date_modified":"2017-05-09T19:47:50.000Z","tags":[".NET","MVVM","C#","Fody"]},{"id":"https://dansiegel.net/post/2017/01/20/using-popup-pages-with-prism-for-xamarin-forms","url":"https://dansiegel.net/post/2017/01/20/using-popup-pages-with-prism-for-xamarin-forms","title":"Using Popup Pages with Prism for Xamarin Forms","summary":"So often as mobile developers we use some sort of Popup view. Really the reasons why we want to do this simple task are pretty endless. For too long it's been...","content_text":"So often as mobile developers we use some sort of Popup view. Really the reasons why we want to do this simple task are pretty endless. For too long it's been something that wasn't an option for Xamarin Forms. Then came one of my favorite new packages [Rg.Plugins.Popup](https://github.com/rotorgames/Rg.Plugins.Popup). The only problem is that the library requires navigation through their Popup Navigation Service instead of being integrated in with the Xamarin Forms.\n\n  \nThis creates an issue for Prism Applications. How do you navigate to Popup Pages while maintaining a proper MVVM pattern? The solution, [Prism.Plugin.Popups](https://github.com/dansiegel/Prism.Plugin.Popups). With Prism.Plugin.Popups, Prism based apps can now navigate to Popup Pages using the Prism INavigationService that you're already using. Best of all, there is no configuration required. The plugin adds several new extensions in the Prism.Navigation namespace, so simply adding the INavigationService to your ViewModel and using the Prism.Navigation namespace is all you need to do.\n\n```csharp\nusing Prism.Navigation;\nusing Prism.Commands;\nusing Prism.Mvvm;\n\nnamespace MyApp.ViewModels\n{\n\tpublic class MainPage : BindableBase\n\t{\n\t\tpublic MainPage( INavigationService navigationService )\n\t\t{\n\t\t\t_navigationService = navigationService;\n\n\t\t\tNavigateCommand = new DelegateCommand( OnNavigateCommandExecuted );\n\t\t}\n\n\t\tINavigationService _navigationService { get; }\n\n\t\tDelegateCommand NavigateCommand { get; }\n\n\t\tprivate async void OnNavigateCommandExecuted() =>\n\t\t\t_navigationService.PushPopupPageAsync( \"MyPopupPage\" );\n\t}\n}\n```\n\nAs mentioned before we're using the INavigationService, and just like the INavigationService you'll need to register your View and/or ViewModel the same as if you're registering any other pages for your application. One caveat to this, in order to function as an extension of the INavigationService it requires specific knowledge of the Container you're using as we have to use your container to resolve the View. As a result there is a container specific implementation for each of the public containers for Prism for Xamarin Forms.","date_published":"2017-01-20T00:29:00.000Z","date_modified":"2017-05-09T19:47:22.000Z","tags":[".NET","Prism","Xamarin","Popups","Xamarin Forms"]},{"id":"https://dansiegel.net/post/2015/12/21/iot-cluster-with-raspberry-pi","url":"https://dansiegel.net/post/2015/12/21/iot-cluster-with-raspberry-pi","title":"IoT Cluster with Raspberry Pi","summary":"IoT has been exploding over the past few years, and nowhere is more evident than with the community surrounding the Raspberry Pi. It is probably one of the most...","content_text":"IoT has been exploding over the past few years, and nowhere is more evident than with the community surrounding the Raspberry Pi. It is probably one of the most versatile ARM platforms being used today. With all of this support we have a wide degree of options.\n\n![IoT Cluster with Raspberry Pi](/images/blog/iot-cluster-with-raspberry-pi/01-image.webp)\n\n5 Raspberry Pi 2's running in a Docker Swarm\n\nEnter Docker... with the benefit of preconfigured images from [Hypriot](http://blog.hypriot.com/downloads/), you can now easily set up a fully functional Docker Swarm in mere minutes. For those who know about Docker, let me start by saying I don't believe you'll learn anything new from this post other than perhaps you can make it work on Raspberry Pi.\n\n  \n\nAs for functionality with Docker Swarm running I was able to quickly deploy a number of services including MariaDB, PostGRE, [Gogs](https://gogs.io/), along with a number of other applications. It really shouldn't come as a huge surprise that you can have highly available services which are easily deployed using Docker, for me what was the most telling factor was the hardware involved.\n\n### Hardware\n\nOne of the first things you may notice about the hardware is I had no real cost for my cables or switch. That's because I pulled out a few old cables and a switch I knew I should throw out but for some reason kept.\n\nQty\n\nItem\n\nCost\n\n5\n\nRaspberry Pi 2\n\n$35/ea\n\n5\n\nMicro Sd Cards\n\n$7/ea\n\n6\n\nCat 5 Cables\n\n$10\n\n1\n\nOld 100mb Switch\n\n$15\n\n### Conclusions\n\nNow I should probably say I would probably not recommend this for a larger business, but when you have an fully functional cluster of actual physical hardware that can provide Enterprise like availability, drawing very little power... I would say this is an excellent feature for small businesses which may be a little shy about having some hosting service host their data in the \"Cloud\".\n\n### Additional Reading\n\n-   [Introducing Hypriot Cluster Lab: Docker clustering as easy as it gets](http://blog.hypriot.com/post/introducing-hypriot-cluster-lab-docker-clustering-as-easy-as-it-gets/) - Dec 8, 2015\n-   [Let Docker Swarm all over your Raspberry Pi Cluster](http://blog.hypriot.com/post/let-docker-swarm-all-over-your-raspberry-pi-cluster/) - July 3, 2015\n\n### Downloads\n\n-   Hypriot Docker Image for Raspberry Pi - Version 0.6.1 Hector - [Download](http://downloads.hypriot.com/hypriot-rpi-20151115-132854.img.zip) - [Checksum](http://downloads.hypriot.com/hypriot-rpi-20151115-132854.img.zip.sha256) - Published 11-15-2015\n-   Hypriot Cluster Lab - Version 0.1 - [Download](http://downloads.hypriot.com/hypriot-rpi-20151128-152209-docker-swarm-cluster.img.zip) - [Checksum](http://downloads.hypriot.com/hypriot-rpi-20151128-152209-docker-swarm-cluster.img.zip.sha25)\\- Published 12-8-2015","date_published":"2015-12-21T06:03:00.000Z","date_modified":"2017-05-09T19:47:07.000Z","tags":["Raspberry Pi","Docker","Iot"]},{"id":"https://dansiegel.net/post/2015/09/01/poor-man-s-design-strategy-for-dynamic-code-in-php","url":"https://dansiegel.net/post/2015/09/01/poor-man-s-design-strategy-for-dynamic-code-in-php","title":"Poor Man's Design Strategy for Dynamic Code in PHP","summary":"Perhaps this has happened to you. You're working on a code base and as you scroll through the code you see something like: I fully admit it drives me absolutely...","content_text":"Perhaps this has happened to you. You're working on a code base and as you scroll through the code you see something like:\n\n```php\nif( $foo == \"bar\" )\n{\n    $name = $foo;\n    # Execute some code\n}\nelse if( $foo == \"fu\" )\n{\n    $name = $foo;\n    # Execute the same code we just did....\n}\nelse if( $foo == \"fubar\" )\n{\n    $name = $foo;\n    # Execute the same code we did the last two times...\n}\n// and so on....\n```\n\nI fully admit it drives me absolutely crazy when I see code that is complete reusable and someone decided to type it out two, three, four, or WTF were you thinking times... It's usually about the time where I am grateful I live in San Diego where we have so many great micro-breweries.\n\n  \n\nA couple of years ago I was working on a code base that had this type of just generally bad code all over the place. On top of this though was the fact that every time a new report page had to be written the Report List Page had to be updated with code like you see above. To make matters worse every time a new report category like \"Admin Reports\" or \"Client Reports\" or \"Billing Reports\" was added an entirely new 'else if' had to be added. The biggest problem was that the code wasn't quite like above it was more like:\n\n```php\n# Admin Reports\n$admin_rows = array( $stuff );\n\n# Client\n$client_rows = array( $stuff );\n\n# Billing\n$billing_rows = array( $stuff );\n\n$table = array(\n    array(\n        $client_rows,\n        $admin_rows\n    ),\n    array(\n        $billing_rows\n    )\n);\n```\n\nThat may not seem so bad, but this ended up in a bloated file that was in excess of 1000 lines of code.\n\n  \n\nThere are always those days for a developer where you can say \"and finally the day came...\", and it did. Finally I had to add a new report and I refused to add to the mess. As is my style, I looked for a solution that had a certain elegance to it, something that could dynamically provide what I needed at runtime. My ultimate goal was to stop having to update the Report List page every time we added a new report.\n\n  \n\nNow to be fair here I did know a few constraints.\n\n-   I knew the possible Report Categories that would exist\n-   I knew that all of the Reports would start with the word 'Reports'\n-   I knew that some reports were used more than once as a different report by passing in different parameters.\n\n  \n\nAs you are probably all too familiar, if you give a thousand programmers a problem you'll get a thousand solutions. What I opted for is what I lovingly refer to as the \"Poor man's Reflection Design Pattern in PHP\". It's of course not quite true reflection but a design pattern that allows us to look at our project's classes for a known attribute to assist us.\n\n### Step 1:\n\n  \n\nThe first thing that I needed was some way of identifying what a particular report was. For this I opted to create an array of hash-tables (aka associative arrays). This allowed me to identify information about each report dynamically and use that to decide how it needed to be constructed.\n\n```php\nclass ReportsFooBar\n{\n    public $report_info = array(\n        array(\n            'category' => 'FooBar',\n            'active' => 1,\n            'order' => 3,\n            'title' => 'Foo...',\n            'description' => 'When things are foo bar',\n            'request' => '?bar=true'\n        )\n    );\n\n    # some more code...\n}\n```\n\n### Step 2:\n\n  \n\nImplement the \"Poor man's reflection design pattern\". This looks at the php classes in a defined space. To save a few processing cycles we discard any classes which did not meet our requirement for starting with Reports. Then we load this into a hash table that will let us get the information we collected to build out our view.\n\n```php\n# Load the local php files with a name containing 'Report'\n# Setup an empty array of reports we will need to build our view for our reports\n$reports = array();\nforeach( $file_array as $key => $filename )\n{\n    # Do some cleanup to get the filename as a class name\n    $report = new $filename();\n    $report_info = $report->{'report_info'};\n\n    # $report_info was not declared in our report class\n    if( !$report_info ) continue;\n\n    # Add report to the report hash\n    for( $i = 0; $i < count( $report_info ); $i++ )\n    {\n        # Set report at $reports[category][order]\n        $reports[strtoupper[$report_info[$i]['category']]][(int)$report_info[$i]['order']] = array(\n            'title' => $report_info['title'],\n            'description' => $report_info['description'],\n            'request' => $report_info['request']\n        );\n    }\n}\n```\n\n### Bonus Step:\n\nThe end result ultimately needed on additional step as you saw above we were doing the same thing over and over. Ultimately for as clever as my solution was to discover reports, it still wasn't good enough. To finish I had to literally make my variable name a variable itself. While I cannot get into the full implementation here, it looked something like:\n\n```php\nforeach( $reports as $category => $report_info )\n{\n    ${\"{$category}_row\"} = array();\n    ${\"{$category}_cell\"} = array();\n    # do foo...\n}\n```","date_published":"2015-09-01T10:58:00.000Z","date_modified":"2017-05-09T19:45:25.000Z","tags":["PHP"]},{"id":"https://dansiegel.net/post/2014/10/13/net-debug-remote-debugging-setup","url":"https://dansiegel.net/post/2014/10/13/net-debug-remote-debugging-setup","title":".NET Debug - Remote Debugging Setup","summary":"We all might try to pretend that the code we wrote is perfect and will never break, but if there is one constant in Software Development it is that no matter how...","content_text":"We all might try to pretend that the code we wrote is perfect and will never break, but if there is one constant in Software Development it is that no matter how genius you were when you wrote your code, you are bound to run into bugs. As every developer is all too aware, debugging can present a real challenge, particularly when the code must be executed from within a specialized environment remote from the developers own computer.\n\n  \n\nAs .NET developers we have transitioned our model to a Cloud First mentality which is to say that all of our processes must work in the cloud including the ability to debug our code. When I found myself suddenly needing to reach out to the Cloud as any developer would I began researching what options were available. It didn’t take long for me to find out that Visual Studio offers free Remote Tools. Unfortunately every article I read seemed to be either out of date or leave just enough information out that it ultimately led me in circles.\n\n  \n\nFrom vNow to vNext, .NET provides one of the friendliest environments for working Cloud First once you understand the tools at your disposal. Regardless of what type of .NET application you have deployed on your Windows Cloud Server, Visual Studio provides you with an easy out of box solution for securely connecting to your live code in the Cloud. While every development situation is a little different, one of the common one’s that I see today is for the Web App Developer. With that in mind here’s a simple guide to go from a fresh Cloud Server to a Web Server that you as a developer can fully utilize to debug your code.\n\n### Checklist:\n\n-   Microsoft Windows Server running Server 2008 or later\n-   Add any Local or Domain Users and Groups that should have access to the Remote Debugging Tools to the Local Administrators Group\n\n### Step 1:\n\n-   Perhaps this should go without saying, but Install the Web Server (IIS) Role. This can be done manually or by using either Web Platform Installer or the included script.\n\n### Step 2:\n\n-   Install Web Deploy 3.5 if you want to deploy your solution directly from within Visual Studio. This should be done from within Web Platform Installer or the included script.\n\n### Cheat:\n\n  \n\n-   Use this PowerShell script to configure the WebServer Role with Web Deploy ( Steps 1 & 2 ) - [Install-WebServerWithWebDeploy.ps1](https://github.com/dansiegel/install-vs-remote-debugging/blob/master/Install-WebServerWithWebDeploy.ps1)\n\n#### \\- OR -\n\n  \n\n-   Install Web Platform Installer.\n-   Install the following packages:\n-   Recommended IIS Configuration ( Step 1 )\n-   Web Deploy 3.5 ( Step 2 )\n\n  \n\n#### \\- OR -\n\n  \n\n-   Recommended IIS Configuration for Hosting Providers ( Steps 1 & 2 )\n-   This includes Web Deploy, PHP 5.3, PHP 5.5, and Node.JS\n\n  \n\nYou should also verify that all of the Features of the Web Server you want are installed.\n\n  \n\n### Step 3:\n\n  \n\nDownload and Install the Remote Tools for the version of Visual Studio you have installed and will be using. The installation process is extremely simple, simply agree to the license and click Install.\n\n![The installer has the same easy flow for vNow to vNext. Agree to the Terms and Conditions and click Install.](/images/blog/net-debug-remote-debugging-setup/01-image.webp)\n\nThe installer has the same easy flow for vNow to vNext.\n\nAgree to the Terms and Conditions and click Install.\n\nFollowing the installation you will need to open the Remote Debugger Configuration Wizard from the Start menu. Since it just seems like a bad practice to leave your server open to anyone to be able to connect to the processes, my suggestion would be to opt for running the Remote Tools as a service. You can use any account you want though running it as the Local System should be fine for most applications.\n\n![Note that there is an option for the Remote Debugger and the Remote Debugger Configuration Wizard. You want the Wizard to set it up as a service.](/images/blog/net-debug-remote-debugging-setup/02-image.webp)\n\nNote that there is an option for the Remote Debugger and the Remote\n\nDebugger Configuration Wizard. You want the Wizard to set it up as a service.\n\n![.NET Debug - Remote Debugging Setup](/images/blog/net-debug-remote-debugging-setup/03-image.webp)\n\n![.NET Debug - Remote Debugging Setup](/images/blog/net-debug-remote-debugging-setup/04-image.webp)\n\nCheck the box to run as a Service. Leave the User name as\n\nLocalSystem or enter the User Credentials you want the\n\nservice to run as.\n\nOnce you’ve configured the Remote Tools to run as a Service; your server is ready for Cloud Development. If you open your Visual Studio Project simply right click the Project and select Publish.","date_published":"2014-10-13T10:21:00.000Z","date_modified":"2017-05-09T19:45:05.000Z","tags":[".NET","C#","Debugging"]}]}