
In past chapters, we built the application architecture on Xamarin so that individual controls can be reused in the most simple way in other applications. In this part, we will wrap these controls into a separate NuGet package, publish it on
nuget.org and try to reuse them in another application, while writing the minimum amount of code.
In the
first and in the
second chapters, we developed an application that consisted of 3 main controls: authorization, product catalog, shopping cart. This is perhaps the typical set for any online store. The structure of the application was as follows:
Authorization → Catalog of goods → Basket.
Initially, the user sees the authorization window, then adds products from the catalog to the basket. Imagine a lamp situation where a customer EXTREMELY wants to change this structure to the following: on the first screen, show immediately the catalog of products that can be viewed, but cannot be added to the basket until the user is authorized to fill the basket in a separate window.

… lyrical digression
In Agile conditions, this situation can occur very often and we, the developers, should be ready for such changes in requirements. Unfortunately, I increasingly encounter situations where, in order to implement such requirements of the customer, the team is working on crutches to release a new version of the application as soon as possible. Gradually, the number of crutches increases, they can generate new bugs and the project becomes difficult to maintain. As a result, it is necessary to spend weeks, or even months, on refactoring of entangled links between modules. On the other hand, it was possible to spend this time at the start of the project to create an architecture ready for such changes. The main idea of ​​this architecture is that controls (self-contained controls) should not depend on other controls so that they can be isolated, changed, combined with each other, etc. But their interaction should be carried out according to the model of subscriptions in one particular place. It turns out that some kind of microservice architecture, but at the front end. :)
Were a little embarrassed, let's proceed to the task.
')
Chapter 1. Creating a NuGet package and publishing it in nuget.org.For the task set forth above, of course, it is not necessary to create nuget packages, but why not simultaneously deal with how it all works. And it works in the truth is very simple. Take the project that we created during the previous 2 articles, it consists of 3 modules: Android, IOS and the so-called Portable Class Library. We will create packages in Visual Studio for Mac.
1) Go to the properties of the PCL project (right mouse button on the project name -> Options)
2) We are looking for the tab NuGet Package → Metadata

Fill in the fields in General. They are required. It is recommended to immediately come up with some kind of unique ID. You can go to the site nugget.org and try to find a library with your ID. If this is not - you can take it. Unfortunately, there is no check for uniqueness right in VS. Version: 1.0.0. The version must be specified exactly so that it would be easier to update the assembly later. Close the window, build the project.
3) Click on the project name with the right mouse button, select the item “Create NuGet Package”

Packages will be created and saved in the <project name> / <project name> / bin / debug / <package ID>. <Version> .nupkg folder.
In my case it is ... / test5 / test5 / bin / debug / my_test_nuget.1.0.0.nupkg
This package we will upload to nuget.org
4) Go to the website nuget.org. Log in / register. Go to the Upload tab, and load the file with the .nupkg permission from item 3.

We can add some additional information and click Submit. We will not find this package in NuGet search (it will appear in it after indexing - usually it is an hour), but this package can be added to any projects via the console ...

If you see such a message, then you did everything right.
Chapter 2. The use of self-sufficient controls in other projectsSo, I created and published controls from previous chapters (authorization, product catalog and shopping cart)
Create a new project and add a published assembly to it. I called it shop_controls_toolkit. You can add it in several ways:
1) From the Nuget console (Install-Package shop_controls_toolkit -Version 1.0.8)
2) Or find it in the NuGet search (Packaged -> Add Package)
Add the necessary controls to MainPage.xaml
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:testapp2" x:Class="testapp2.testapp2Page" xmlns:controls="clr-namespace:testcontrols;assembly=testcontrols"> <Grid> <controls:ProductsListing x:Name="listing"></controls:ProductsListing> <Grid x:Name="menu"> <controls:AuthorizationView x:Name="auth"></controls:AuthorizationView> <controls:BasketView x:Name="basket"></controls:BasketView> </Grid> <Button Clicked="Handle_Clicked" Image="burger.png"> </Button> </Grid> </ContentPage>
It is necessary to register xmlns so that at this level the controls from the added library are visible.
xmlns:controls="clr-namespace:testcontrols;assembly=testcontrols"
For the corresponding visual effect, you also need to specify the location of the Vertical and Horizontal Options controls.
In the code-behind, you need to initialize the use of all controllers and services from the testcontrols library, you can do this, for example, in the App.cs constructor
testcontrols.Core.DI.Bootstrapper.RegisterIoC();
You also need to subscribe to the appropriate services, as described in part 2.
public testapp2Page() { InitializeComponent(); _authService = Container.GetInstance<IAuthorizationService>(); _authService.AuthorizationChanged += AuthService_AuthorizationChanged; listing.AddProductRequest += Listing_AddProductRequest; } void AuthService_AuthorizationChanged(bool isAuth) { if(isAuth) { basket.IsVisible = true; auth.IsVisible = false; } else { basket.IsVisible = false; auth.IsVisible = true; } }
Those. show the cart or authorization depending on whether a person is authorized.
Similarly, you can subscribe to events in the listing of goods. For example, we want to restrict the addition of goods to the cart so that they can be added only when an authorized client.
Subscribe in the designer for the Action control of the AddProductRequest product catalog
async void Listing_AddProductRequest(string sku) { if(_isAuth) { _basketService.StartAddingProduct(sku); return; } await DisplayAlert("", $" , ", ""); }
Well, then you can subscribe to the entire event without delving into the implementation of the controls itself. BasketService also has fields such as TotalCount or TotalPrice ...
Update Nuget PackagesIf suddenly we want to update something in the control library, we need to increase the project version in the project's Options, and upload the file with the enlarged version on nuget.org. . Nuget itself will understand that this is just a new version of an existing library, and will update its version.
After a while (usually up to 10 minutes) in the project that uses this library, a label will appear next to the name of the assembly, which will mean that the version can be updated. Updating ...

That's all.
Thanks to this approach, we can create different controls, wrap them in a separate NuGet package and reuse it in all applications.
You can overload the package initialization method, where additional settings will be available, for example: URL back-end API of the application, data cache storage time, etc., to make controls even more universal. In the application we will not delve into the implementation of these controls - the main thing is to use them correctly. The speed of development will increase, the number of crutches will decrease, and our managers will be happy with the speed of making the changes necessary for the business.
→ The project
is available in GitHubIt is interesting what Habr's users think about this approach - leave comments. We are planning to create a universal library for any online store in order to simplify the creation of such B2C or B2B applications.
Read previous articles in the cycle
here and
here .