简体   繁体   中英

MVVM sharing code Win8 and WP8 and file access

I am working on small project, where I would like to learn about code sharing methods. This solution include both Win8 and WP8 projects.

I need to load data from XML files which are stored in the memory of specific device. ( Package.Current.InstalledLocation.Path - Win8 and IsolatedStorage - WP8) and I am working with PCL for sharing code on assembly level.

I also would like to use repository pattern for getting data from XML files but in case of every system(Win8 and WP8) has different file access method I also plan to use something like IFileStorage but I do not know how to connect these two in a good way to be able to use specific IFileStorage in the concrete project in ViewModel. I am using MVVM Light Toolkit and here is a GitHub repo of this solution.

I would consider using the MvvmCross plugins. These do exactly as you mention and have an interface which your shared Portable Class Library works with, then has platform specific versions which can be place into an IOC container.

MvvmCross Plugins are here: https://github.com/slodge/MvvmCross/tree/v3/Plugins/Cirrious

MvvmCross is here: https://github.com/slodge/MvvmCross

You mention you are using Mvvm Light. Oren Novotney has a portable Mvvm Library that you can use inside of a portable class library. Check it out here .

Your next step will be to design controller interfaces that your platform-specific instances will implement. Then, all you have to do is register your platform-specific controller at app init. The portable libraries will be able to access them directly and you can have platform specific implementations.

You can use WinRT API to access files in WP8 and Win8:

public class LocalFileStorage: IRepository<byte[]> 
    {
        private readonly string _fileName;

        public LocalFileStorage(string fileName)
        {
            _fileName = fileName;
        }

        public async Task<byte[]> LoadAsync()
        {
            try
            {
                var file = await GetFileAsync();
                using (var stream = await file.OpenStreamForReadAsync())
                {
                    var buffer = new byte[stream.Length];
                    await stream.ReadAsync(buffer, 0, buffer.Length);
                    return buffer;
                }
            }
            catch (Exception e)
            {
                throw new RepositoryException("Unable load data from repository", e);
            }
        }

        public async Task SaveAsync(byte[] buffer)
        {
            try
            {
                var file = await GetFileAsync();
                using (var stream = await file.OpenStreamForWriteAsync())
                {
                    await stream.WriteAsync(buffer, 0, buffer.Length);
                }
            }
            catch (Exception e)
            {
                throw new RepositoryException("Unable save data to repository", e);
            }
        }

        private async Task<StorageFile> GetFileAsync()
        {
            StorageFile file = null;
            var notFound = false;

            try
            {
                file = await ApplicationData.Current.LocalFolder.GetFileAsync(_fileName);
            }
            catch (FileNotFoundException)
            {
                notFound = true;
            }

            if (notFound)
            {
                file = await ApplicationData.Current.LocalFolder.CreateFileAsync(_fileName);
            }

            return file;
        }
    }

I use a Factory to create a repository for a ViewModel :

 public class FileStorageFactory: IRepositoryFactory
    {
        private const string SOME_FILE_NAME_1 = "FileName1.xml";
        private const string SOME_FILE_NAME_2= "FileName2.xml";

        public IRepository<byte[]> CreateFor1()
        {
            return new LocalFileStorage(SOME_FILE_NAME_1 );
        }

        public IRepository<byte[]> CreateFor2()
        {
            return new LocalFileStorage(SOME_FILE_NAME_2);
        }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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