简体   繁体   English

使用Xamarin.Forms和Xamarin Studio的基本存储

[英]Basic Storage using Xamarin.Forms and Xamarin Studio

I have been going around and around for hours with a seemingly simple task of storing very basic information in a Xarmarin.Forms PCL app. 我已经在一个看似简单的任务中走了好几个小时,这个任务是将非常基本的信息存储在Xarmarin.Forms PCL应用程序中。 All I want to do is have a user enter one thing into an Entry field and then save that to Android and IOS devices. 我要做的就是让用户在Entry字段中输入一件事,然后将其保存到Android和IOS设备。

Everything I see I can't get to work in Xamarin Studio (Such as installing nuget packages). 我看到的所有内容我都无法在Xamarin Studio中使用(例如安装nuget软件包)。

Performing file I/O using a shared PCL project is a little trickier than you might expect; 使用共享的PCL项目执行文件I / O比您预期的要复杂一些。 the core Xamarin Forms framework doesn't expose any of the System.IO classes one would use to do this, which can leave you pretty puzzled at first. 核心的Xamarin Forms框架不会公开任何System.IO类,而这会使您一开始很困惑。 If you think about it a bit, it makes a certain amount of sense; 如果您仔细考虑一下,它在一定程度上是有意义的。 after all, each platform is going to have its own implementation for the I/O infrastructure. 毕竟,每个平台都将有自己的I / O基础结构实现。 However, that doesn't make it any less frustrating when all you're trying to do is write to a bleeping file. 但是,当您试图做的只是向一个正在流血的文件中写入内容时,这并不会因此而感到沮丧。

This is where the DependencyService comes in! 这是DependencyService进来的地方! The designers of the Xamarin Forms framework understood that people would want to write code in a shared assembly but still need access to platform-specific implementations of things such as low-level file access. Xamarin Forms框架的设计人员了解到,人们希望在共享程序集中编写代码,但仍然需要访问平台特定的实现,例如低级文件访问。 To support this use case, Xamarin Forms exposes a simple MEF-like dependency-injection framework that allows you to register implementations of interfaces via attribution. 为了支持该用例,Xamarin Forms公开了一个简单的类似于MEF的依赖项注入框架,该框架使您可以通过归因来注册接口的实现。

The DependencyService framework has a simple recipe: define an interface in an assembly that will be referenced by your platform-specific code (the Android, iOS, WinPhone projects), define implementation classes in the platform-specific asssemblies, and register the implementation classes with the Dependency attribute (see the Xamarin Docs for more information). DependencyService框架有一个简单的配方:在程序集中定义一个接口,该接口将由您的平台特定的代码(Android,iOS,WinPhone项目)引用,在平台特定的程序集中定义实现类,并向其中注册实现类Dependency属性(有关更多信息,请参见Xamarin文档 )。

For a simple project, the shared PCL will be fine. 对于简单的项目,共享的PCL很好。 In more complex projects, I'd recommend a dedicated "Common" assembly that contains interfaces, shared types, etc. In this case, we can define an interface that exposes some simple functionality: 在更复杂的项目中,我建议使用一个专用的“通用”程序集,其中包含接口,共享类型等。在这种情况下,我们可以定义一个暴露一些简单功能的接口:

using System;

namespace MyDemo
{
    public interface IFileService
    {
        void WriteData(String data);
        String ReadData();
    }
}

Next up, we'll create an implementation for our Android and iOS platforms. 接下来,我们将为我们的Android和iOS平台创建一个实现。 Create a class that implements the interface. 创建一个实现该接口的类。 It is important that it have a parameterless constructor, as the DependencyService currently does not provide a way to pass in any constructor arguments: 具有无参数构造函数很重要,因为DependencyService当前不提供传递任何构造函数参数的方法:

namespace MyDemo
{
    public class FileService : IFileService
    {
        public FileService()
        {
        }

        public void WriteData(String data)
        {
            string filePath = Path.Combine(
            Environment.GetFolderPath(Environment.SpecialFolder.Personal),
            "Data.txt");
            System.IO.File.WriteAllText(filePath, data);
        }

        public String ReadData()
        {
            string filePath = Path.Combine(
            Environment.GetFolderPath(Environment.SpecialFolder.Personal),
            "Data.txt");
            var data = System.IO.File.ReadAllText(filePath);
            return data;
        }
    }
}

Finally, add an attribute that exports this implementation: 最后,添加一个导出此实现的属性:

[assembly: Xamarin.Forms.Dependency(typeof(MyDemo.FileService))]
namespace MyDemo
{
    public class FileService : IFileService
    ...

It's VERY important that the Dependency attribute be placed outside the namespace declaration; 将Dependency属性放置在名称空间声明之外非常重要; you can be left scratching your head trying to understand why you're getting null references even though you have apparently done everything right. 您可能会费劲地试图理解为什么即使您显然已正确完成了所有操作,但为什么仍会得到空引用。

Finally, in your shared project's code, use the DependencyService to resolve the implementation at runtime: 最后,在共享项目的代码中,使用DependencyService在运行时解析实现:

var fileService = DependencyService.Get<IFileService>();
fileService.WriteData("Hello!");
var data = fileService.ReadData();
System.Diagnostics.Debug.WriteLine(data);

Obviously, you will want something a little more advanced than my example, but this should get you started. 显然,您将需要比我的示例更高级的功能,但这应该可以帮助您入门。

Hope this helps! 希望这可以帮助!

Charles Petzold在他的电子书《 使用Xamarin创建移动应用程序》中还使用DependencyService为所有三个平台的File helper编写了大量代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM