<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Amit</title>
    <description>The latest articles on DEV Community by Amit (@parallelthreads).</description>
    <link>https://dev.to/parallelthreads</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F607608%2F316ce9f5-50ac-49ec-80c1-dd041a3a77a3.jpg</url>
      <title>DEV Community: Amit</title>
      <link>https://dev.to/parallelthreads</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/parallelthreads"/>
    <language>en</language>
    <item>
      <title>Real-time data visualization and alerts using Redis TimeSeries, Grafana and Slack.</title>
      <dc:creator>Amit</dc:creator>
      <pubDate>Wed, 13 Dec 2023 06:37:01 +0000</pubDate>
      <link>https://dev.to/parallelthreads/real-time-data-visualization-and-alerts-using-redis-timeseries-grafana-and-slack-5674</link>
      <guid>https://dev.to/parallelthreads/real-time-data-visualization-and-alerts-using-redis-timeseries-grafana-and-slack-5674</guid>
      <description>&lt;p&gt;In any non-trivial application, each part of the system generates a substantial amount of data. Whatever be the domain, we want to observe, monitor, and act on this data. &lt;/p&gt;

&lt;p&gt;We will explore visualization of real-time data in Grafana and while Prometheus is usually what is associated with in such scenarios, we will look at Redis TimeSeries. &lt;br&gt;
We will create a dashboard for a simple app that generates a continuous stream of data and store it in Redis as Time Series data and visualize in Grafana, and configure alerts via Slack. &lt;/p&gt;
&lt;h4&gt;
  
  
  Application and Data
&lt;/h4&gt;

&lt;p&gt;The client is a simple .NET console app that sends memory usage data on the Windows client, with an introduced delay of 750 milliseconds. This data includes total system memory usage (which is what is visualized) and memory used by each process.&lt;/p&gt;

&lt;p&gt;The server is a basic Node.js app, and for simplicity it uses WebSocket connection as we have a steady stream of data being received. This data is then passed on to the primary Redis instance which will accept the incoming writes.&lt;/p&gt;

&lt;p&gt;Note: &lt;br&gt;
The client and the server apps are developed to get the data flowing in and do not follow any best practices like retries, error handling, configuration, logging etc. &lt;br&gt;
In the current dev setup, the Node.js server, Redis and Grafana all run on the same Mac.&lt;/p&gt;
&lt;h4&gt;
  
  
  Configuring Redis
&lt;/h4&gt;

&lt;p&gt;Installing Redis on Mac is straightforward following the &lt;a href="https://redis.io/docs/getting-started/installation/install-redis-on-mac-os/" rel="noopener noreferrer"&gt;instructions here&lt;/a&gt;. We have 2 Redis instances running - one to accept the writes and the other, from which Grafana will pull the data for visualization. There is significant documentation on &lt;a href="https://redis.io/docs/management/replication/" rel="noopener noreferrer"&gt;replication&lt;/a&gt; and &lt;a href="https://redis.io/docs/management/persistence/" rel="noopener noreferrer"&gt;persistence&lt;/a&gt; in Redis and for this example, the second instance acts as a read-only replica which is replicated asynchronously.&lt;/p&gt;

&lt;p&gt;We use the &lt;a href="https://github.com/RedisTimeSeries/RedisTimeSeries/" rel="noopener noreferrer"&gt;Redis TimeSeries&lt;/a&gt; type which, as the name suggests,¬ stores time series data. The type expects the value to be numeric and that is what we have - a series of numbers representing the memory utilization, in Megabytes, at that point in time. &lt;/p&gt;

&lt;p&gt;For every data point, the key is the current timestamp, and the memory utilization number is the value. At this point, we have the data in memory, in the format we need, which can be visualized on a dashboard.&lt;/p&gt;

&lt;p&gt;Note: We have a single Windows client here, but we can have multiple clients with a label for each time series data entry to query on. &lt;/p&gt;
&lt;h4&gt;
  
  
  Grafana and the Dashboard
&lt;/h4&gt;

&lt;p&gt;Grafana is an open-source data visualization and monitoring solution - it allows us to query, visualize, set alerts and more for the data at hand. In this example, Grafana is &lt;a href="https://grafana.com/docs/grafana/latest/setup-grafana/installation/" rel="noopener noreferrer"&gt;setup&lt;/a&gt; to run locally on the Mac. After installation, the webpage is available at &lt;a href="http://localhost:3000" rel="noopener noreferrer"&gt;http://localhost:3000&lt;/a&gt; where you can sign-in with the default credentials of admin/admin (and change the password). &lt;/p&gt;

&lt;p&gt;First order of business in Grafana is to set up a dashboard with the data source of our choice, in this case Redis. You can &lt;a href="https://grafana.com/docs/grafana/latest/getting-started/build-first-dashboard/" rel="noopener noreferrer"&gt;create a new dashboard&lt;/a&gt; and provide Redis as the data source for the dashboard.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi3a77v0ydi3ojywbfczk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi3a77v0ydi3ojywbfczk.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The screenshot shows the dashboard with Redis as the source and TimeSeries as the type. There are several commands available but the one we are interested is the TS.GET to fetch the data. You can also notice on the right side the numerous ways to customize the visualization with tool-tips, legend, graph styles etc.&lt;/p&gt;

&lt;p&gt;We also apply a Transformation on the data for visualization where it creates a new data frame for each pair of data being received.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0wm7xp9f8o0hnyumne4u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0wm7xp9f8o0hnyumne4u.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once the entire setup is up and running, we can see the data show up in the dashboard as a continuously updated graph of memory utilization over time.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/AxLD38yghVE"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h4&gt;
  
  
  Slack Alerts for High-Memory Usage
&lt;/h4&gt;

&lt;p&gt;Now that we have the dashboard setup and we can visualize the data, it would be nice if we could do something other than just looking at the graph. &lt;br&gt;
As it is system memory usage, let’s say that we want to be notified if total system memory usage crosses 7000 MB on the client machine. To achieve this, an alert rule is configured where Grafana will notify on a Slack channel.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fadup5shwo7dda44zimfh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fadup5shwo7dda44zimfh.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The alert also allows configuring options like how long it should evaluate the alert condition, how often to check for the condition, silencing options and more.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm03pweb1o6eamxksh6u7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm03pweb1o6eamxksh6u7.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here as we are using Slack, we first need to configure it to allow an &lt;a href="https://api.slack.com/messaging/webhooks" rel="noopener noreferrer"&gt;incoming webhook&lt;/a&gt; (This webhook allows POST to the provided URL and is not shared anywhere other than in the Grafana notification setting).&lt;br&gt;
Once added, you should see the notifications in Slack when the alert condition is met. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnx1srmaztvtsufomnntw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnx1srmaztvtsufomnntw.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Grafana supports notification templates which can be reused across different types of notification contact points and messages can be configured and formatted too. &lt;br&gt;
It also supports a whole bunch of options when it comes to alerting other than Slack. &lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/huyRyyVUY0I"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Here are the GitHub links for the &lt;a href="https://github.com/AmitEMV/SystemResourceData" rel="noopener noreferrer"&gt;Windows client app&lt;/a&gt;, and the &lt;a href="https://github.com/AmitEMV/dataHandler" rel="noopener noreferrer"&gt;Node.js service&lt;/a&gt; with the Redis configs and Grafana dashboard/alert rule export.&lt;/p&gt;

&lt;p&gt;Cover image credit: Photo by &lt;a href="https://unsplash.com/@markuswinkler?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash" rel="noopener noreferrer"&gt;Markus Winkler&lt;/a&gt; on &lt;a href="https://unsplash.com/photos/black-and-silver-laptop-computer-IrRbSND5EUc?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

</description>
      <category>grafana</category>
      <category>slack</category>
      <category>dashboard</category>
      <category>redis</category>
    </item>
    <item>
      <title>Cross-Platform app with C# and Uno Platform - Part 2</title>
      <dc:creator>Amit</dc:creator>
      <pubDate>Mon, 09 Aug 2021 18:10:00 +0000</pubDate>
      <link>https://dev.to/parallelthreads/cross-platform-app-with-c-and-uno-platform-part-2-2b84</link>
      <guid>https://dev.to/parallelthreads/cross-platform-app-with-c-and-uno-platform-part-2-2b84</guid>
      <description>&lt;p&gt;In part 1, I covered a bit of intro to Uno Platform and the app built on it. I'll close with some thoughts on cross platform development, challenges and alternatives for Uno Platform here and wrap up.   &lt;/p&gt;

&lt;h3&gt;
  
  
  Let's talk Cross Platform
&lt;/h3&gt;

&lt;p&gt;Single codebase means simpler maintenance - a feature upgrade is a single change for all platforms. This also means simpler testing and build pipeline too, as you don't need one for every platform or the associated language used for that platform. It does make a good case for itself and seems pretty logical when you think about it, right? If your team is proficient in C# then you're good. If not, how long are you willing to wait, if you are willing to? &lt;/p&gt;

&lt;p&gt;You can visit the technology showcase section of &lt;a href="https://platform.uno/showcases/" rel="noopener noreferrer"&gt;Uno Platform&lt;/a&gt;, &lt;a href="https://reactnative.dev/showcase" rel="noopener noreferrer"&gt;React Native&lt;/a&gt;, &lt;a href="https://flutter.dev/showcase" rel="noopener noreferrer"&gt;Flutter&lt;/a&gt; and &lt;a href="https://dotnet.microsoft.com/platform/customers/xamarin" rel="noopener noreferrer"&gt;Xamarin&lt;/a&gt; and it looks like there are quite a few of them. &lt;br&gt;
On the flip side, there's this article from &lt;a href="https://medium.com/airbnb-engineering/sunsetting-react-native-1868ba28e30a" rel="noopener noreferrer"&gt;Airbnb&lt;/a&gt; and one from &lt;a href="https://dropbox.tech/mobile/the-not-so-hidden-cost-of-sharing-code-between-ios-and-android" rel="noopener noreferrer"&gt;Dropbox&lt;/a&gt; as well, where they went back to native. &lt;/p&gt;

&lt;p&gt;So, does a single, shared codebase work for everyone or not? Only way to find out is probably by trying out a sample (and slightly complicated app) and see how it goes, or an internal non-customer facing app to get a feel of how it would work. &lt;/p&gt;
&lt;h3&gt;
  
  
  Third-Party UI Controls for Uno Platform
&lt;/h3&gt;

&lt;p&gt;In the previous post, I mentioned Windows Community Toolkit for UI controls, but in .NET apps on Windows (WPF, UWP, ASP.NET Core etc.) you have a lot of options for third party controls. With Uno, the &lt;a href="https://platform.uno/docs/articles/supported-libraries.html?q=syncfusion#control-libraries" rel="noopener noreferrer"&gt;documentation&lt;/a&gt; lists Syncfusion and Infragistics. Now this app that I have created, is a cut-down version of the Web Assembly version that I created with Blazor. The main reason for this is I don't have those chart controls here for me.&lt;/p&gt;

&lt;p&gt;With Syncfusion, it required adding their entire project locally to the solution to integrate it and there was no license specified at that time, so I skipped it. It seems to be &lt;a href="https://github.com/syncfusion/Uno.SfChart/issues/11" rel="noopener noreferrer"&gt;resolved now though&lt;/a&gt;. Infragistics looks good too but they have a trial license which I didn't go for at that time.&lt;/p&gt;

&lt;p&gt;I cannot comment on these as I haven't used them but they are available for Uno. &lt;/p&gt;
&lt;h3&gt;
  
  
  What about Mac?
&lt;/h3&gt;

&lt;p&gt;I started out with the target to have the app run on Windows, Mac, Linux and Android. It worked fine on all except for the Mac. This is due to the way I have created the sample and let's see what that is. UWP allows us to set visual breakpoints and set visual state for each of those. As seen in &lt;a href="https://docs.microsoft.com/en-us/windows/apps/design/basics/xaml-basics-adaptive-layout" rel="noopener noreferrer"&gt;this example&lt;/a&gt; -&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;x:Double x:Key="MinWindowBreakpoint"&amp;gt;0&amp;lt;/x:Double&amp;gt;
&amp;lt;x:Double x:Key="MediumWindowBreakpoint"&amp;gt;641&amp;lt;/x:Double&amp;gt;
&amp;lt;x:Double x:Key="LargeWindowBreakpoint"&amp;gt;1008&amp;lt;/x:Double&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can then specify the Data Template, to optimize the view for that size, and this gets triggered depending on the dimensions specified in the breakpoint. Think of this as a CSS media query, to make it easier to relate to.&lt;br&gt;
In our case, I also have the &lt;a href="https://github.com" rel="noopener noreferrer"&gt;command in the viewmodel&lt;/a&gt; that fetches data on startup, asynchronously. This data is being bound to the DataGrid which is present in the above Data Template. This somehow doesn't work on Mac, while it works fine on other platforms. &lt;br&gt;
I have &lt;a href="https://github.com/unoplatform/uno/issues/6375" rel="noopener noreferrer"&gt;opened a GitHub issue&lt;/a&gt; for this and until then, I have the app in Mac without any data, to show that it does launch and also is responsive (visual adaptive breakpoints).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4wm38d6r126s7213d6nk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4wm38d6r126s7213d6nk.png" alt="App with default width on Mac"&gt;&lt;/a&gt; &lt;br&gt;With Default Width
   &lt;/p&gt;

&lt;p&gt;if I minimize the app horizontally, it gets to the small breakpoint and readjusts accordingly/&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1vljxfgtntzt3dq8rp7a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1vljxfgtntzt3dq8rp7a.png" alt="Responsive small width"&gt;&lt;/a&gt; &lt;br&gt;Reduced width to see the responsive UI
   &lt;/p&gt;

&lt;h3&gt;
  
  
  The Players
&lt;/h3&gt;

&lt;p&gt;There are quite a few alternatives and I'll just list them here as I haven't tried all of them.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://flutter.dev/" rel="noopener noreferrer"&gt;Flutter&lt;/a&gt; - Google's UI toolkit offering, using Dart.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://reactnative.dev/" rel="noopener noreferrer"&gt;React Native&lt;/a&gt; - Apps for Android and iOS, using React.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://microsoft.github.io/react-native-windows/" rel="noopener noreferrer"&gt;React Native for Windows and Mac&lt;/a&gt; - An interesting option to bring React Native apps to Windows and Mac! &lt;/li&gt;
&lt;li&gt;
&lt;a href="https://dotnet.microsoft.com/apps/xamarin" rel="noopener noreferrer"&gt;Xamarin&lt;/a&gt; - Extending .NET to multiple platforms including watchOS and tvOS. &lt;/li&gt;
&lt;li&gt;
&lt;a href="https://docs.microsoft.com/en-us/dotnet/maui/what-is-maui" rel="noopener noreferrer"&gt;.NET MAUI&lt;/a&gt; - Evolution of Xamarin.Forms, currently in preview.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.electronjs.org/" rel="noopener noreferrer"&gt;Electron&lt;/a&gt; - Cross platform desktop apps for Windows\Mac\Linux. VS Code is built with Electron. &lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What Next?
&lt;/h3&gt;

&lt;p&gt;Probably one last port of this app to .NET MAUI, Microsoft's upcoming offering, for comparison. React Native for Windows and Mac looks good for experimenting too.&lt;/p&gt;

&lt;p&gt;Choice is good.&lt;/p&gt;

&lt;p&gt;Cover image &lt;a href="https://pixabay.com/photos/doors-choices-choose-decision-1767562/" rel="noopener noreferrer"&gt;credit&lt;/a&gt;&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>mobile</category>
      <category>dotnet</category>
    </item>
    <item>
      <title>Cross-Platform app with C# and Uno Platform - Part 1</title>
      <dc:creator>Amit</dc:creator>
      <pubDate>Mon, 09 Aug 2021 17:57:02 +0000</pubDate>
      <link>https://dev.to/parallelthreads/writing-a-cross-platform-app-with-c-and-uno-platform-lop</link>
      <guid>https://dev.to/parallelthreads/writing-a-cross-platform-app-with-c-and-uno-platform-lop</guid>
      <description>&lt;p&gt;If you are developing an app, you want to reach as many users as you can and the easiest and the most obvious target is a web application. It is easily accessible irrespective of the platform users are on. However, not all applications\scenarios can be delivered through a browser and this is why we have desktops\laptops, wearables and mobile apps. So now you have to write software that supports these platforms as well. Will life be easier if you could write code just once that would work on all these platforms? &lt;/p&gt;

&lt;h3&gt;
  
  
  So, desktops\laptops and mobile -  that's 2 categories?
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Only&lt;/em&gt; 2 platforms (or form factors) - desktops\laptops can be Windows, Mac or Linux. Phones are either Android or iOS. This is not even considering the huge market of Tablets and Wearables. It is &lt;em&gt;also&lt;/em&gt; not considering the various versions of those devices running various versions of the operating system on them. &lt;/p&gt;

&lt;p&gt;&lt;br&gt;
    &lt;a href="https://i.giphy.com/media/BmmfETghGOPrW/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/BmmfETghGOPrW/giphy.gif" alt="Zack gif"&gt;&lt;/a&gt;&lt;br&gt;&lt;p&gt;&lt;a href="https://giphy.com/gifs/reaction-BmmfETghGOPrW" rel="noopener noreferrer"&gt;via GIPHY&lt;/a&gt;&lt;/p&gt;
    &lt;br&gt;
 &lt;/p&gt;

&lt;p&gt;In this article, we will take a look at &lt;a href="https://platform.uno/" rel="noopener noreferrer"&gt;Uno Platform&lt;/a&gt; to develop our app for Windows, Mac, Linux and Android.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; We will discuss a bit more about cross-platform development, challenges and alternatives to the Uno Platform in part 2 of this article.&lt;/p&gt;
&lt;h3&gt;
  
  
  What is Uno Platform?
&lt;/h3&gt;

&lt;p&gt;Uno Platform is an &lt;a href="https://github.com/unoplatform" rel="noopener noreferrer"&gt;open source&lt;/a&gt; UI platform to build apps with a single codebase that can target a wide variety of platforms. You write code in C# and XAML to target all these platforms. It builds on &lt;a href="https://platform.uno/how-it-works/" rel="noopener noreferrer"&gt;existing capabilities provided by each platform&lt;/a&gt; internally, so that you can focus on developing your app. It does allow you to add\modify the app's behaviour based on where your app is running. &lt;/p&gt;

&lt;p&gt;&lt;br&gt;
    &lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvw738luvxbqxapmf3zpk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvw738luvxbqxapmf3zpk.png" alt="Uno Platform Architecture"&gt;&lt;/a&gt;&lt;br&gt;&lt;p&gt;Source:&lt;a href="https://github.com/unoplatform/uno/blob/master/doc/articles/what-is-uno.md" rel="noopener noreferrer"&gt;Uno Platform&lt;/a&gt;&lt;/p&gt;
    &lt;br&gt;
 &lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/unoplatform/uno/blob/master/doc/articles/how-uno-works.md" rel="noopener noreferrer"&gt;GitHub docs&lt;/a&gt; has a good summary on how Uno works for build, runtime and rendering across platforms.&lt;/p&gt;
&lt;h3&gt;
  
  
  Simple app with Uno
&lt;/h3&gt;

&lt;p&gt;We will look at creating a simplified version of the Portfolio Tracker web app that I &lt;a href="https://dev.to/parallelthreads/building-a-web-app-with-asp-net-core-blazor-webassembly-13kj"&gt;previously wrote about&lt;/a&gt;. The constraint I have imposed is, I shouldn't have to modify my service or database. It has to work with the existing set of APIs. &lt;br&gt;
My requirement boils down to this -&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use this current available data and write an app that runs on Windows, Linux, Mac and Android.&lt;/li&gt;
&lt;li&gt;Reuse as much code as possible from the previous Web Assembly project that I've created.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Uno supports more platforms than the ones I'm targeting. It supports iOS, Tizen and Web Assembly as well. I cannot try out iOS and Tizen so I've excluded those and since I already tried out Web Assembly using Blazor I didn't include that as well.&lt;/p&gt;

&lt;p&gt;I have used Visual Studio 2019 on Windows and Visual Studio 2019 for Mac. Uno Platform getting started guide for both platforms are available &lt;a href="https://platform.uno/docs/articles/get-started-vs.html" rel="noopener noreferrer"&gt;here&lt;/a&gt;. &lt;/p&gt;
&lt;h3&gt;
  
  
  Project structure
&lt;/h3&gt;

&lt;p&gt;Here is the Visual Studio project structure for this app - &lt;/p&gt;

&lt;p&gt;&lt;br&gt;
    &lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F90rt03cpirfwvd96en8k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F90rt03cpirfwvd96en8k.png" alt="Visual Studio Project Structure"&gt;&lt;/a&gt;&lt;br&gt;Uno Platform Visual Studio Project Structure (in Windows)
    &lt;br&gt;
 &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The Mac target project is unloaded as it is not supported on Windows.&lt;/li&gt;
&lt;li&gt;The Shared project is only a list of files. They are shared by each target platform and built for each as well. &lt;/li&gt;
&lt;li&gt;Each target project can have items specific to itself - fonts and image assets for each platform are couple of examples.&lt;/li&gt;
&lt;li&gt;Any reference\NuGet package to be added, has to be added to all target platforms.&lt;/li&gt;
&lt;li&gt;MainPage.xaml in the shared project is where the navigation is setup using the &lt;a href="https://docs.microsoft.com/en-us/windows/apps/design/controls/navigationview" rel="noopener noreferrer"&gt;NavigationView&lt;/a&gt;. Also the default view is set in Main.xaml.cs and in this case, Dashboard is set as default.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  The code
&lt;/h3&gt;

&lt;p&gt;From the actual code perspective, it is writing a C#\XAML UWP app. We're working on the UI and we need UI controls. I will come back to this in part 2 to talk a bit more but I will mention the Windows Community Toolkit here. There is a section in the &lt;a href="https://platform.uno/docs/articles/uno-community-toolkit.html?tabs=tabid-vswin" rel="noopener noreferrer"&gt;docs&lt;/a&gt; on how to use it, which is ported onto other platforms. I did include DataGrid, NavigationView, ProgressBar in the project and it worked fine. &lt;br&gt;
I could not try out gesture support as I tried the app in the Android emulator and not on a physical device.&lt;br&gt;
In a real production app, it may be the case that we will need platform specific behaviour. I didn't really have such a scenario for this app but I wanted to try it out anyway, so this is what I did - on Android I wanted the navigation menu to be the hamburger menu (3 stacked dashes), on the top left. For desktops\laptops, we have plenty of screen space so I did not want a hamburger menu and instead as menu items with the selected one being underlined.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
#if __ANDROID__
    RootNavigationView.PaneDisplayMode = NavigationViewPaneDisplayMode.Auto;
#else
    RootNavigationView.PaneDisplayMode = NavigationViewPaneDisplayMode.Top;
#endif

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Uno does support platform specific code both in &lt;a href="https://platform.uno/docs/articles/platform-specific-csharp.html" rel="noopener noreferrer"&gt;C#&lt;/a&gt; and via &lt;a href="https://platform.uno/docs/articles/platform-specific-csharp.html" rel="noopener noreferrer"&gt;XAML&lt;/a&gt; as well.&lt;/p&gt;

&lt;p&gt;Couple of app screenshots here from Linux and Android - Linux was a virtual machine on Windows 10 running Kubuntu 18.04. &lt;/p&gt;

&lt;p&gt;&lt;br&gt;
    &lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsfqfy3my0tonh8cvqq3x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsfqfy3my0tonh8cvqq3x.png" alt="App running in Linux"&gt;&lt;/a&gt;&lt;br&gt;C# UI app in Linux
    &lt;br&gt;
 &lt;/p&gt;

&lt;p&gt;Android screenshot is from the emulator as I didn't root my phone to install this locally developed app. Yeah the app does not look great, thanks to my choice of painting it gray.&lt;/p&gt;

&lt;p&gt;&lt;br&gt;
    &lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmxlr5yspqyyulib9i53y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmxlr5yspqyyulib9i53y.png" alt="Same app running in the Android Emulator"&gt;&lt;/a&gt;&lt;br&gt;Same app running in the Android Emulator
    &lt;br&gt;
 &lt;/p&gt;

&lt;h3&gt;
  
  
  How is Uno so far?
&lt;/h3&gt;

&lt;p&gt;You can target a wide variety of platforms with a single codebase and that is neat. It includes Web Assembly as well so it covers the browser space too. In the app,  the code in the folders under Shared project (Models, Interfaces, Services, Helpers etc.) are code that I've used as-is from the previous project. This is the &lt;strong&gt;biggest advantage&lt;/strong&gt; I've seen writing this app with Uno. I have my service and database and I have all the code to fetch and handle it. The focus is only on building the UI. Unless we need\want to do something platform specific, Uno abstracts it from us. &lt;br&gt;
XAML Hot Reload is super useful, especially if we're used to, say React development for example. Uno does have an active Discord channel where core members participate, which is encouraging to see. &lt;br&gt;
There is also decent support for 3rd party libraries (I'm excluding UI controls here, which I talk about in part 2) including presentation frameworks like MVVM Light and theming options like Material UI as well.  &lt;/p&gt;

&lt;p&gt;Link to the &lt;a href="https://github.com/AmitEMV/PortfolioTrackerCrossPlatform" rel="noopener noreferrer"&gt;GitHub repo for this app&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Cover image &lt;a href="https://pixabay.com/photos/kings-cross-station-london-england-1647741/" rel="noopener noreferrer"&gt;credit&lt;/a&gt;  &lt;/p&gt;

</description>
      <category>csharp</category>
      <category>mobile</category>
      <category>dotnet</category>
    </item>
    <item>
      <title>Working with ASP.NET Core Blazor WebAssembly</title>
      <dc:creator>Amit</dc:creator>
      <pubDate>Wed, 28 Apr 2021 15:00:05 +0000</pubDate>
      <link>https://dev.to/parallelthreads/working-with-asp-net-core-blazor-webassembly-55ak</link>
      <guid>https://dev.to/parallelthreads/working-with-asp-net-core-blazor-webassembly-55ak</guid>
      <description>&lt;p&gt;In the previous part I went over the app details but didn't really talk about the development experience. I'll close with some thoughts on that here in this second part.  &lt;/p&gt;

&lt;h3&gt;
  
  
  Dev experience - Visual Studio
&lt;/h3&gt;

&lt;p&gt;I'm using Visual Studio 2019 Community Edition and have encountered some issues in debugging, which are already being tracked\planned for future -&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://docs.microsoft.com/en-us/aspnet/core/blazor/debug?view=aspnetcore-5.0&amp;amp;%3Btabs=visual-studio&amp;amp;tabs=visual-studio"&gt;Breakpoint limitations&lt;/a&gt; - specifically the OnInitializedAsync part. There are workarounds &lt;a href="https://github.com/dotnet/aspnetcore/issues/29335"&gt;like&lt;/a&gt; this which are available.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/dotnet/aspnetcore/issues/27883"&gt;No hot reload, yet&lt;/a&gt; - you need to re-launch the app for a code change. There is an option to debug with &lt;em&gt;dotnet watch run&lt;/em&gt; though. &lt;/li&gt;
&lt;li&gt;Sometimes locals\watch wouldn't work for me, but I can't specifically recall exactly when that occurred.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Working with Blazor
&lt;/h3&gt;

&lt;p&gt;When creating the app, you get an option to select if you want to make it a PWA, which I did. I was able to install the app from the browser without any additional setting, which is pretty neat. The &lt;a href="https://docs.microsoft.com/en-us/aspnet/core/blazor/progressive-web-app?view=aspnetcore-5.0&amp;amp;tabs=visual-studio"&gt;documentation&lt;/a&gt; does cover details about push notifications and service workers but I didn't try that out for this app.&lt;br&gt;
It is also straightforward to have a responsive design and then have the appropriate styling\CSS to make those look better. The app is usable on a mobile form-factor, but it definitely should be better and that's not Blazor's fault, it's mine :)&lt;br&gt;
I have published the app to IIS but here's a &lt;a href="https://timheuer.com/blog/deploy-blazor-webassembly-applications-on-azure-using-github-actions-wasm/"&gt;detailed blog&lt;/a&gt; on various deployment options.&lt;br&gt;
Since it is a web app already running in a browser, you can take advantage of existing tools like Lighthouse to audit the app and look for ways to improve accessibility, performance, SEO etc.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--yhKDSeZo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/65qjketral16uhzridzz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--yhKDSeZo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/65qjketral16uhzridzz.png" alt="Downloading Compressed Assets"&gt;&lt;/a&gt;&lt;br&gt;Downloading Compressed Assets
  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cmd9lnc8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/18cs9p1hbnsefbhxpxo3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cmd9lnc8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/18cs9p1hbnsefbhxpxo3.png" alt="Downloading Uncompressed Assets"&gt;&lt;/a&gt;&lt;br&gt;Downloading Uncompressed Assets
  &lt;/p&gt;

&lt;p&gt;Above screenshots are taken on Chrome on Mac, loading the app published to IIS on Windows 10 on a different laptop. They compare network data transfer that includes stylesheets, Radzen components, .NET dependencies etc and that's ~4.4 MB vs ~9.9 MB for uncompressed. That's a good compression ratio but it'll be good to see some data for complex apps with more data and dependencies and see how it performs. The second image also shows the app in an almost mobile form factor with the menu shifted up.&lt;/p&gt;

&lt;h3&gt;
  
  
  Third-party Controls
&lt;/h3&gt;

&lt;p&gt;Blazor has a quite a few third party libraries\controls available. Here's one of the few lists which link many resources available for Blazor, in particular the libraries piece -  &lt;a href="https://github.com/AdrienTorris/awesome-blazor#libraries--extensions"&gt;https://github.com/AdrienTorris/awesome-blazor#libraries--extensions&lt;/a&gt;&lt;br&gt;
You do have lot of free, paid or open source options. I tried &lt;a href="https://www.syncfusion.com/products/communitylicense"&gt;Syncfusion Community License&lt;/a&gt; and they're good (with support too) . I used &lt;a href="https://blazor.radzen.com/"&gt;Radzen&lt;/a&gt; in the app and it worked well. &lt;br&gt;
&lt;em&gt;I couldn't try all available libraries and this isn't a sponsored post&lt;/em&gt;  &lt;/p&gt;

&lt;h3&gt;
  
  
  What next?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;The app itself, has a lot of to-do items. It needs multi-user support and login, &lt;strong&gt;unit tests&lt;/strong&gt;, improvements so that it doesn't fetch data on every page switch, accessibility etc. It also &lt;em&gt;should&lt;/em&gt; be served over https which is not the case in my local setup. &lt;/li&gt;
&lt;li&gt;Try comparing with some other front end technology, like React, for development experience and performance.
&lt;/li&gt;
&lt;li&gt;Couple of things announced by Microsoft to explore building native\hybrid and cross platform apps using &lt;a href="https://docs.microsoft.com/en-us/mobile-blazor-bindings/"&gt;Explore Blazor Mobile Bindings&lt;/a&gt; and also &lt;a href="https://devblogs.microsoft.com/xamarin/the-new-net-multi-platform-app-ui-maui/"&gt;.NET MAUI&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>dotnet</category>
      <category>csharp</category>
      <category>webassembly</category>
    </item>
    <item>
      <title>Building a Web App with ASP.NET Core Blazor WebAssembly</title>
      <dc:creator>Amit</dc:creator>
      <pubDate>Wed, 28 Apr 2021 14:45:27 +0000</pubDate>
      <link>https://dev.to/parallelthreads/building-a-web-app-with-asp-net-core-blazor-webassembly-13kj</link>
      <guid>https://dev.to/parallelthreads/building-a-web-app-with-asp-net-core-blazor-webassembly-13kj</guid>
      <description>&lt;p&gt;There are various options available today to create a web app, and usually at work, you can't pick up every new framework or technology that pops up. However, we can always experiment with one (or more) and build a hobby project. I've tried creating one such app with Blazor WebAssembly and also write my first article along with it.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is Blazor?
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://dotnet.microsoft.com/apps/aspnet/web-apps/blazor" rel="noopener noreferrer"&gt;Blazor&lt;/a&gt; is an open source client side framework to build web apps using C# instead of JavaScript. It can be considered, functionally, as an alternative to React\Angular etc. to write web apps\SPAs, though it is new and the tooling is evolving. &lt;/p&gt;

&lt;h3&gt;
  
  
  Why Blazor WebAssembly?
&lt;/h3&gt;

&lt;p&gt;JavaScript (and the libraries\frameworks around it) is the more popular choice when it comes to web apps. There were other options like Flash, Silverlight etc. though not standardized (and not relevant anymore).&lt;/p&gt;

&lt;p&gt;With &lt;a href="https://webassembly.org/" rel="noopener noreferrer"&gt;WebAssembly&lt;/a&gt;, things get bit more interesting. WebAssembly enables code written in programming languages (C#, C++, Rust, etc) other than JavaScript to run on the browser and it certainly does help that it is an open standard as well. Also, all the major browsers - Firefox\Chrome\Edge\Safari, support WebAssembly already. &lt;/p&gt;

&lt;p&gt;Coming back to Blazor, it has &lt;a href="https://docs.microsoft.com/en-us/aspnet/core/blazor/hosting-models?view=aspnetcore-5.0" rel="noopener noreferrer"&gt;two hosting models&lt;/a&gt; for the app to run either on a browser or on the server with ASP.NET Core. I want to try build a web app, in the traditional sense that has all client code downloaded in the browser and talks to some REST endpoints, and see how it compares to building such an app using say React. &lt;br&gt;
 &lt;br&gt;
    &lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Faspnet%2Fcore%2Fblazor%2Findex%2F_static%2Fblazor-webassembly.png%3Fview%3Daspnetcore-5.0" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Faspnet%2Fcore%2Fblazor%2Findex%2F_static%2Fblazor-webassembly.png%3Fview%3Daspnetcore-5.0"&gt;&lt;/a&gt;&lt;br&gt;Source: &lt;a href="https://docs.microsoft.com/en-us/aspnet/core/blazor/?view=aspnetcore-5.0#blazor-webassembly" rel="noopener noreferrer"&gt;Microsoft Docs&lt;/a&gt;
    &lt;br&gt;
 &lt;/p&gt;

&lt;h3&gt;
  
  
  The Node.js Effect
&lt;/h3&gt;

&lt;p&gt;I would like to draw a parallel with Node.js - the availability of JavaScript as a runtime on the server gained significant traction. But why even talk about that here? The evolution of WebAssembly and its support for various programming languages (specifically C# in this context), to me, feels like something similar on the client side of things. Say you have a .NET desktop app or a web service, if there is a reusable piece of logic, it can then be used pretty much as is on the web now.&lt;br&gt;
Of course it is too early to say, but given the browser support and growing tooling, it could get widespread adoption.  &lt;/p&gt;

&lt;h3&gt;
  
  
  Simple app with Blazor WebAssembly
&lt;/h3&gt;

&lt;p&gt;Coming to the actual web application, it is a simple mutual funds portfolio tracker. You pick the funds you want to track, enter some details and save it. The app displays basic info like % returns, value trend, top gainers, top losers, ability to add\delete mutual funds and has few graphs. &lt;strong&gt;&lt;em&gt;The funds are randomly picked, I'm not an investment expert and this is not investment advice&lt;/em&gt;&lt;/strong&gt; :) &lt;/p&gt;

&lt;p&gt;Some details about how the app is structured -&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The data is sourced  from  &lt;a href="https://www.mfapi.in/" rel="noopener noreferrer"&gt;https://www.mfapi.in/&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;I've picked a few prominent funds from the above website and stored the historical data into a MySQL database. JSON result from the above API source is parsed and the historical data is stored for these funds.&lt;/li&gt;
&lt;li&gt;The app itself is hosted in IIS on Windows 10&lt;/li&gt;
&lt;li&gt;I also have an ASP.NET Core Web API for my REST endpoints, which interfaces between the app and the database. This repo has the scripts for creating tables and inserting some of these funds data into it.
Here are couple of screenshots from the app -

&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffsiix7f9fr1wwuvrnk2e.png" alt="Dashboard View"&gt;Dashboard View

&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdjq5h262wb3wwmqb8u1u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdjq5h262wb3wwmqb8u1u.png" alt="Manage Portfolio View"&gt;&lt;/a&gt;&lt;br&gt;Manage Portfolio View
  &lt;/p&gt;

&lt;h3&gt;
  
  
  Project Structure
&lt;/h3&gt;

&lt;p&gt;This is the Visual Studio project structure for the web app - &lt;br&gt;
 &lt;br&gt;
    &lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fofmfzhncmrbjrqgh7gy5.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fofmfzhncmrbjrqgh7gy5.PNG" alt="Visual Studio Project Structure"&gt;&lt;/a&gt;&lt;br&gt;Blazor WebAssembly Visual Studio Project Structure
    &lt;br&gt;
 &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The menu items are specified in the NavMenu.razor file which is included inside the sidebar div of the MainLayout.razor. This menu is responsive, if you resize the browser you can notice that it transforms to a hamburger menu.&lt;/li&gt;
&lt;li&gt;All references for your services and third party components are specified in the _Imports.razor file.&lt;/li&gt;
&lt;li&gt;Pages are the individual pages that are loaded, to which users are routed to based on the menu item that is clicked. Each page has the &lt;em&gt;&lt;a class="mentioned-user" href="https://dev.to/page"&gt;@page&lt;/a&gt;&lt;/em&gt; directive and that is the same value mapped in the NavMenu.&lt;/li&gt;
&lt;li&gt;I've made some changes to the app.css in the wwwroot folder to handle styling&lt;/li&gt;
&lt;li&gt;The services should preferably have an interface and the corresponding implementation for each, which I don't have as of now. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Also, the &lt;a href="https://docs.microsoft.com/en-us/aspnet/core/blazor/project-structure?view=aspnetcore-5.0#blazor-webassembly" rel="noopener noreferrer"&gt;official documentation&lt;/a&gt; has some more details on the project structure. &lt;/p&gt;

&lt;p&gt;Here are the links to the GitHub repo for the &lt;a href="https://github.com/AmitEMV/MutualFundsTracker" rel="noopener noreferrer"&gt;Blazor UI app&lt;/a&gt; and the repo for the &lt;a href="https://github.com/AmitEMV/MutualFundsAPI" rel="noopener noreferrer"&gt;Web API project&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the second part of this article, I go over some thoughts on development experience and conclude.&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>webassembly</category>
      <category>csharp</category>
    </item>
  </channel>
</rss>
