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
.
中注册依赖项
用谷歌搜索了一段时间,但没有找到真正好的东西。
所以,在 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
.