MvvmCross 和 PCL 服务层 - 如何使用 OS 特定功能

MvvmCross and PCL Service Layer - how to use OS specific functions

用谷歌搜索了一段时间,但没有找到真正好的东西。

所以,在 MVVM Cross 指南中,我们的解决方案(针对移动平台)是分开的,例如 HelloWorld.Core 项目和少数平台特定项目,例如 HelloWorld.Android.UI.

你可以在这里看到完整的教程https://www.mvvmcross.com/documentation/tipcalc-tutorial/the-tip-calc-tutorial

而且,问题是,在我们的 .Core 项目中,我们创建了服务、ViewModel,并在 MVVM Cross 提供的 IoC 容器中注册了它。

在MvvmCross文档提供的示例中Service实现非常简单,就这么一个函数

    public class CalculationService: ICalculationService
    {
        public double TipAmount(double subTotal, int generosity)
        {
            return subTotal * ((double)generosity)/100.0;
        }
    }

所以我们继续,在我们的 App.cs 中注册它,然后它可以在绑定 ViewModel

中使用
public class App: MvxApplication
    {
        public App()
        {
            Mvx.RegisterType<ICalculationService, CalculationService>();
            Mvx.RegisterSingleton<IMvxAppStart>(new MvxAppStart<HomeViewModel>());
        }
    }

查看型号代码:

public class TipViewModel : MvxViewModel
    {
        readonly ICalculation _calculation;

        public TipViewModel(ICalculation calculation)
        {
            _calculation = calculation;
        }

    // ...

        double _tip;

        public double Tip
        {
            get {
                return _tip;
            }
            set
            {
                _tip = value;
                RaisePropertyChanged(() => Tip);
            }
        }

        void Recalculate()
        {
            Tip = _calculation.TipAmount(SubTotal, Generosity);
        }
    }

但问题是,当我开始研究它时,我决定,比方说,编写一些简单的本地存储数据扫描程序来查找一些特定文件。

简单代码示例:

 public class SimpleDataScanner : IBaseDataScanner
    {
        private string _basePath { get; set; }

        private List<string> _scanResult { get; set; }

        public SimpleDataScanner()
        {
            _basePath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
            _scanResult = new List<string>();
        }

        public List<string> BasicDataScan(string startPath = null)
        {
            string startFolder = _basePath;

            if (startPath.Length > 0 && startPath.Length != null)
            {
                startFolder = Path.Combine(_basePath, startPath);
            }

            try
            {
                TreeScan(startFolder);
            }
            catch (Exception)
            {

                throw;
            }

            return _scanResult;

        }

        private void TreeScan(string path)
        {
            foreach (var file in Directory.GetFiles(path))
            {
                if (Path.HasExtension("pdf"))
                {
                    _scanResult.Add(file);
                }
            }
            foreach (string dir in Directory.GetDirectories(path))
            {
                TreeScan(dir);
            }
        }
    }

而且,正如我发现的那样,问题是:

1) 我无法在 PCL

中使用 Android 特定函数和属性

2) 我无法在我的 PCL Core 项目中使用引用,比方说,一些其他 Android class lib 项目

所以,我无法创建工作服务,这意味着我无法在 IoC 容器中注册它并传递给 ViewModel。

这样做的方法是什么? 任何教程?还是我理解错了?

您需要在您的平台代码中实现该接口,并在您的平台项目中的Setup.cs中针对该接口注册具体实现。因此,在您的情况下,IDataScanner 将存在于您的 Core 项目中,而 SimpleDataScanner 将存在于 Android 项目中。

Setup.cs 中,您将像这样注册具体实现:

protected override void InitializeFirstChance()
{
    base.InitializeFirstChance();

    Mvx.RegisterSingleton<IDataScanner>(() => new SimpleDataScanner());
}

本质上,如果接口需要特定于平台的代码或完整的 .NET 框架代码来实现,则那些基于平台的实现存在于平台中并在平台设置中注册。如果接口和实现都在 Core 项目内共享,则可以在 App.cs.

中注册依赖项