Xamarin.Forms ile Katmanlı Mimariye Giriş – 8 Paketleme

Merhabalar,

Serimizin bu yazısında geliştirmiş olduğumuz base projemizi diğer projelerde de kullanmak için nuget package haline getireceğiz.

Paketleme işlemleri için çok fazla yöntem var fakat ben nuget cli kullanarak yapacağım.

https://docs.microsoft.com/en-us/nuget/create-packages/creating-a-package
  • Nuget.exe dosyasını indiriyoruz.
  • Paketleyeceğimiz proje klasörüne gidip, nuget.exe dosyasını bu klasör içerisine taşıyoruz ve command line açıyoruz.
  • Nuget spec komutunu çalıştırıyoruz.
  • Gerekli düzenlemeleri yapmak için oluşan .spec dosyasını bir text editor ile açıyoruz.
  • Nuget pack komutu ile paketleme işlemini tamamlıyoruz.
Paketleyeceğimiz proje klasörüne gidip, nuget.exe dosyasını bu klasör içerisine taşıyoruz ve command line açıyoruz.
<?xml version="1.0" encoding="utf-8"?>
<package >
  <metadata>
    <id>$id$</id>
    <version>$version$</version>
    <title>$title$</title>
    <authors>$author$</authors>
    <requireLicenseAcceptance>false</requireLicenseAcceptance>
    <license type="expression">MIT</license>
    <projectUrl>http://project_url_here_or_delete_this_line/</projectUrl>
    <iconUrl>http://icon_url_here_or_delete_this_line/</iconUrl>
    <description>$description$</description>
    <releaseNotes>Summary of changes made in this release of the package.</releaseNotes>
    <copyright>$copyright$</copyright>
    <tags>Tag1 Tag2</tags>
  </metadata>
</package>

Gerekli yerleri isteğimize göre düzenliyoruz.

<?xml version="1.0" encoding="utf-8"?>
<package >
  <metadata>
    <id>Xamarin.MyXF</id>
    <version>1.0.0</version>
    <authors>Yigit Ozaksut</authors>
    <requireLicenseAcceptance>false</requireLicenseAcceptance>
    <license type="expression">MIT</license>
    <projectUrl>https://github.com/ozaksuty/MyXF/</projectUrl>
    <iconUrl>https://cdn2.iconfinder.com/data/icons/vivid/48/rocket-512.png</iconUrl>
    <description>MyXF is simple and wrapped framework for Xamarin.Forms</description>
    <releaseNotes>v1.0.0 stable</releaseNotes>
    <copyright>Copyright 2021</copyright>
    <tags>Xamarin, Refit, Polly, Fusillade, AppCenter</tags>
    <dependencies>
		    <dependency id="acr.userdialogs" version="7.1.0.475" /> 
			<dependency id="autofac" version="6.1.0" /> 
			<dependency id="fusillade" version="2.3.1" />
			<dependency id="microsoft.appcenter" version="4.1.0" /> 
			<dependency id="microsoft.appcenter.analytics" version="4.1.0" />
			<dependency id="microsoft.appcenter.crashes" version="4.1.0" /> 
			<dependency id="microsoft.appcenter.distribute" version="4.1.0" />
			<dependency id="modernhttpclient-updated" version="3.4.3" />
			<dependency id="polly" version="7.2.1" /> 
			<dependency id="refit" version="5.2.4" />
			<dependency id="rg.plugins.popup" version="2.0.0.10" />
    </dependencies>
  </metadata>
</package>

Projemizin kullandığı dependecyleri eklememiz çok önemli.

nuget pack komutu ile Xamarin.MyXF.1.0.0.nupkg dosyamızı oluşturuyoruz.

Test etmek için yeni bir Xamarin.Forms projesi açıyoruz.

Oluşturmuş olduğumuz private paketi localimizden yüklemek ve test etmek için Package Manager kısmına klasör yolunu ekliyoruz.

Package Manager > Browse kısmına geldiğimizde sağdaki kaynağı “MyXF Package Source” olarak değiştirdiğimizde oluşturmuş olduğumuz paketi göreceğiz.

Tüm projeleri seçip, paketi yüklüyorum.

Projemizin “Packages” kısmına paketimizin geldiğini göreceğiz.

Paketimizi yükledikten sonra yapımızı kullanmak için gerekli sayfaları ve sınıfları oluşturuyoruz.

Uygulamamızın, geliştirdiğimizi yapı üzerinden çalışması için gerekli Init işlemini yapıyoruz.

        public App()
        {
            InitializeComponent();
            ViewModelLocator.Init<AppShellPageViewModel>(Assembly.GetExecutingAssembly());
        }

GlobalSetting sınıfı içerisindeki tüm yardımcı propertyleri isteğimiz doğrultusunda kullanabiliriz.

<?xml version="1.0" encoding="utf-8" ?>
<Shell xmlns="http://xamarin.com/schemas/2014/forms"
       xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
       xmlns:viewModelBase="clr-namespace:MyXF.Client.mobilebase.ViewModels.Base;assembly=MyXF.Client.mobilebase"
       viewModelBase:ViewModelLocator.AutoWireViewModel="true"
       xmlns:pages="clr-namespace:TestApp1.Pages"
       x:Class="TestApp1.Pages.AppShellPage">
    <ShellContent ContentTemplate="{DataTemplate pages:MainPage}"/>
</Shell>

xmlns:viewModelBase artık MyXF.Client üzerinden set edileceğine dikkat etmeliyiz. Çünkü MyXF.Client içerisindeki yapıyı kullanacağız.

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:viewModelBase="clr-namespace:MyXF.Client.mobilebase.ViewModels.Base;assembly=MyXF.Client.mobilebase"
             viewModelBase:ViewModelLocator.AutoWireViewModel="true"
             x:Class="TestApp1.Pages.MainPage">
    <ContentPage.Content>
        <StackLayout>
            <Button Text="Dialog Service Test"
                Command="{Binding DialogCommand}"/>
        </StackLayout>
    </ContentPage.Content>
</ContentPage>
    public class MainPageViewModel : ViewModelBase
    {
        public override Task InitializeAsync(object navigationData)
        {
            return base.InitializeAsync(navigationData);
        }
        public ICommand DialogCommand => new Command(() =>
        {
            DialogService.AlertAsync("Dialog Service", "Test", "Ok");
        });
    }

Paket Güncelleme

Kullandığımız yapı üzerinde yeni geliştirmeler yaptığımızda, bu yapıyı hazırladığımız paket üzerinden kullanan projelere bir güncelleme çıkmamız gerekiyor.

ApiRequestSelector sınıfımızda düzeltmemiz gereken AppCenter işlemleri olduğunu unutmayalım 🙂

        public T GetApiRequestByPriority(IApiRequest<T> apiRequest, PriorityType priorityType, [CallerMemberName] string methodName = "")
        {
            Analytics.TrackEvent($"CallerMemberName: {methodName}",
                new Dictionary<string, string>
                {
                    {
                        "Time", DateTime.Now.ToString()
                    }
                });

            switch (priorityType)
            {
                case PriorityType.Speculative:
                    return apiRequest.Speculative;
                case PriorityType.UserInitiated:
                    return apiRequest.UserInitiated;
                case PriorityType.Background:
                    return apiRequest.Background;
                default:
                    return apiRequest.UserInitiated;
            }
        }

GetApiRequestByPriority methodu içerisinde kullandığımız Analytics.TrackEvent methodunu IAppCenterService interface üzerinden tüketmeliyiz.

IAppCenterService

    public interface IAppCenterService : IServiceBase
    {
        void Init();
        bool HandleApiException(ApiException ex);
        void HandleException(Exception ex);
        void Log(string name, IDictionary<string, string> properties = null);
    }

AppCenterService

        public void Log(string name, IDictionary<string, string> properties = null)
        {
            Analytics.TrackEvent($"CallerMemberName: {name}", properties);
        }

ApiRequestSelector

        public T GetApiRequestByPriority(IApiRequest<T> apiRequest, PriorityType priorityType, [CallerMemberName] string methodName = "")
        {
            _appCenterService.Log(methodName,
                new Dictionary<string, string>
                {
                    {
                        "Time", DateTime.Now.ToString()
                    }
                });

            switch (priorityType)
            {
                case PriorityType.Speculative:
                    return apiRequest.Speculative;
                case PriorityType.UserInitiated:
                    return apiRequest.UserInitiated;
                case PriorityType.Background:
                    return apiRequest.Background;
                default:
                    return apiRequest.UserInitiated;
            }
        }

Şimdi nuget paketimizi güncelleyip, TestApp1 projemizde güncelleyeceğiz.

Öncelikli olarak MyXF.Client.mobilebase.nuspec dosyamızdaki version parametresini değiştirerek güncel paketi oluşturacağız. İstersek releaseNotes gibi parametrelieri de değiştirebiliriz.

<?xml version="1.0" encoding="utf-8"?>
<package >
  <metadata>
    <id>Xamarin.MyXF</id>
    <version>1.0.1</version>
    <authors>Yigit Ozaksut</authors>
    <requireLicenseAcceptance>false</requireLicenseAcceptance>
    <license type="expression">MIT</license>
    <projectUrl>https://github.com/ozaksuty/MyXF/</projectUrl>
    <iconUrl>https://cdn2.iconfinder.com/data/icons/vivid/48/rocket-512.png</iconUrl>
    <description>MyXF is simple and wrapped framework for Xamarin.Forms</description>
    <releaseNotes>v1.0.1 - Added new Log method to IAppCenterService and refactor ApiRequestSelector.cs</releaseNotes>
    <copyright>Copyright 2021</copyright>
    <tags>Xamarin, Refit, Polly, Fusillade, AppCenter</tags>
    <dependencies>
      <dependency id="acr.userdialogs" version="7.1.0.475" />
      <dependency id="autofac" version="6.1.0" />
      <dependency id="fusillade" version="2.3.1" />
      <dependency id="microsoft.appcenter" version="4.1.0" />
      <dependency id="microsoft.appcenter.analytics" version="4.1.0" />
      <dependency id="microsoft.appcenter.crashes" version="4.1.0" />
      <dependency id="microsoft.appcenter.distribute" version="4.1.0" />
      <dependency id="modernhttpclient-updated" version="3.4.3" />
      <dependency id="polly" version="7.2.1" />
      <dependency id="refit" version="5.2.4" />
      <dependency id="rg.plugins.popup" version="2.0.0.10" />
    </dependencies>
  </metadata>
</package>

“nuget pack” komutu ile Xamarin.MyXF.1.0.1.nupkg dosyasını elde edeceğiz.

TestApp1 projemizde Nuget – Solution kısmına gittiğimizde güncellemeyi direkt görebiliyoruz. Güncelleme işlemini yaptıktan sonra 1.0.1 versiyonunu kullanmaya başlayabiliriz.

Oluşturduğunuz paketleri kullanan mobil projeler için daha yönetilebilir ve kullanılabilir yapılar kurmak tamamen bizim elimizde.

Changelog : https://github.com/ozaksuty/MyXF/commit/89a7955584cff3b6cfbff1c5fb96fafc8e0f9953

Yiğit

Xamarin Developer, Consultant & Architect. Community Leader and Director of Xamarin Türkiye

Post A Reply