3

我将 Freshmvvm 用于我的 Xamarin 表单项目。我正在使用相机并想使用特定于平台的功能。所以,我想知道如何使用 IOC 控件来使用特定于平台的功能。

Freshmvvm.FreshIOC.Container.Register<ICamera,Camera>();

如果我从 App 类调用此代码,我是否需要在 iOS 和 Android 项目中都有相机类,如果是,那么如何让应用类知道我们想要实现一个特定平台的相机类?还是有更好的方法来使用 IOC 控制并将接口注入到页面模型(视图模型)的构造器中,当我们想要使用它时?

4

3 回答 3

4

我认为您所追求的是Dependency Service。这使您能够访问本机功能。

这样,您必须在共享代码中创建一个接口,例如ICamera

public interface ICamera
{
   void TakePicture();
}

现在您可以在平台特定项目中实现此接口。

例如在 iOS 上,你可以这样实现它:

public class CameraImplementation : ICamera { public void TakePicture() { // iOS 代码在这里 } }

现在这里的关键是你如何注册它。您可以通过在平台特定实现的命名空间上方添加这样的标签来做到这一点,如下所示:

[assembly: Xamarin.Forms.Dependency (typeof (CameraImplementation))]
namespace yourapp
{
   // CameraImplementation class here
}

安卓也是如此。如果您保持命名相同,您甚至可以复制并粘贴此标签。

于 2016-09-14T20:13:59.710 回答
3

免责声明:我对 IOC、DI 和 FreshMvvm 非常陌生。刚刚为自己工作,并想分享以帮助其他人,以防万一他们像我一样偶然发现了这个论坛。

Xamarin Forms 提供的DependencyService非常棒,但仍然有限(例如,无法实现构造函数注入)。在使用 DependencyService 的同时实现单元测试也会变得有点麻烦。如果您坚持使用 DependencyService 但又想对代码进行单元测试,这里有一个教程将引导您完成一些步骤。它是一个服务定位器,比依赖注入更难(在我看来)测试。

我没有使用它,而是使用 FreshMvvm 的 IOC 来访问特定于平台的代码。@WickedW 所说的一切都是完全正确的。我只是稍微调整了最后一步。

而不是直接解决依赖关系:

IFileHelper fileHelper = FreshMvvm.FreshIOC.Container.Resolve<IFileHelper>();
string dbPath = fileHelper.GetLocalFilePath("CoreSQLite.db3");

我使用了构造函数注入:

Public class MainPageModel : FreshBasePageModel
{
    public string YourLabelText { get; set;}
    IFileHelper _fileHelper;
    public MainPageModel(IFileHelper fileHelper)
    {
        _fileHelper = fileHelper
    }

    // This is implemented by FreshBasePageModel
    public override void Init(object initData)
    {
        YourLabelText = _fileHelper.GetLocalFilePath(“CoreSQLite.db3”);
    }   
}

确保在加载应用程序之前注册您的平台特定类:

FreshMvvm.FreshIOC.Container.Register<IFileHelper, FileHelper>();
global::Xamarin.Forms.Forms.Init();
LoadApplication(new App());

return base.FinishedLaunching(app, options);

我必须这样做,因为我在 App.xaml.cs 的构造函数中解析了 MainPageModel:

public App()
    {
        InitializeComponent();

        var page = FreshPageModelResolver.ResolvePageModel<MainPageModel>();
        var navContainer = new FreshNavigationContainer(page);
        MainPage = navContainer;
    }

@WickedW 完全正确地实现了特定于平台的实现,然后我只是使用 Michael Ridland 的FreshMvvm n=2视频来计算构造函数注入,因为这是我个人需要的功能。希望这可以帮助像我一样努力解决这个问题的人。

于 2019-03-19T17:42:52.907 回答
2

Xamarin Forms 中内置的 DependencyService 可以完成这项业务,但如果您只想在 FreshMvvm 中使用 IOC,您可以 -

a) 在 Forms Init 方法附​​近注册您的平台特定类(IOS 如下)-

public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
        global::Xamarin.Forms.Forms.Init();

        InitIoc();

        LoadApplication(new App());

        return base.FinishedLaunching(app, options);
}

private void InitIoc()
{
        FreshMvvm.FreshIOC.Container.Register<IFileHelper, FileHelper>();
}

与往常一样,您的班级存在于平台一侧-

public class FileHelper : IFileHelper
{
    public string GetLocalFilePath(string filename)
    {
        string docFolder = Environment.GetFolderPath(Environment.SpecialFolder.Personal);

然后在您的 PCL / Forms 项目中使用它时解析该类 -

IFileHelper fileHelper = FreshMvvm.FreshIOC.Container.Resolve<IFileHelper>();
string dbPath = fileHelper.GetLocalFilePath("CoreSQLite.db3");

...
于 2017-09-26T07:17:42.737 回答