使用 Prism 在 Xamarin Forms 的后台服务中实现依赖注入

2024-04-28

我在我的 xamarin 表单项目中使用 Prism。我能够在我的视图模型中使用依赖注入(构造函数注入),没有任何问题。我还利用后台服务在后台推送长时间运行的任务。如何做我在后台服务中注入依赖项?当我尝试将接口对象作为参数传递给构造函数(SyncingBackgroundingCode)时,对象(SqliteService)为空。我已经在依赖项注入容器中注册并解析了对象。 如何处理这种情况?任何人都可以提供示例或链接来实现这种情况吗?

这是我尝试实现依赖注入的代码片段。

This is in Droid :-

    public class AndroidSyncBackgroundService : Service
         {
        CancellationTokenSource _cts;
        public override IBinder OnBind (Intent intent)
        {
        return null;
        }
        public override StartCommandResult OnStartCommand (Intent intent, StartCommandFlags flags, int startId)
         {
        _cts = new CancellationTokenSource ();
        Task.Run (() => {
                try {
                //INVOKE THE SHARED CODE
                var oBackground = new SyncingBackgroundingCode();
                oBackground.RunBackgroundingCode(_cts.Token).Wait();
            }
            catch (OperationCanceledException) 
        {

        }
        finally {
        if (_cts.IsCancellationRequested) 
        {
                var message = new CancelledTask();
        Device.BeginInvokeOnMainThread (
                                    () => MessagingCenter.Send(message, "CancelledTask")
                );
            }
            }
            }, _cts.Token);
        return StartCommandResult.Sticky;
            }


        public override void OnDestroy ()
        {
        if (_cts != null) {
            _cts.Token.ThrowIfCancellationRequested ();

        _cts.Cancel ();
            }
        base.OnDestroy ();
            }
        }

    This is in PCL:-


         public class SyncingBackgroundingCode
                {
                    public SQLiteConnection _sqlconnection;
                    SqliteCalls oSQLite = new SqliteCalls();
                ISqliteService _SqliteService;

                public SyncingBackgroundingCode(ISqliteService SqliteService)
                {
                //object is null
                }

                    public async Task RunBackgroundingCode(CancellationToken token)
                    {
                            DependencyService.Get<ISQLite>().GetConnection();

                        await Task.Run (async () => {

                            token.ThrowIfCancellationRequested();

                            if (App.oSqliteCallsMainLH != null)
                            {                 
                                App.bRunningBackgroundTask = true;

                                oSQLite = App.oSqliteCallsMainLH;
                                await Task.Run(async () =>
                                {
                                    await Task.Delay(1);
                                    oSQLite.ftnSaveOnlineModeXMLFormat("Offline", 0); 
                                    oSQLite.SyncEmployeeTableData();
                                    oSQLite.SaveOfflineAppCommentData();
                                    oSQLite.SaveOfflineAdditionToFlowData();
                                    await Task.Delay(500);

                                    var msgStopSyncBackgroundingTask = new StopSyncBackgroundingTask();
                                    MessagingCenter.Send(msgStopSyncBackgroundingTask, "StopSyncBackgroundingTask");  
                                });

                            }

                        }, token);
                    }
                }

不幸的是,Xamarin 和 Xamarin Forms 没有提供像 Prism 这样的框架来处理 IoC 场景。不过,有几种方法可以解决这个问题。

首先,容器是后台服务中 PrismApplication 上的公共属性,您可以执行以下操作:

public class FooBackgroundService
{
    private App _app => (App)Xamarin.Forms.Application.Current;

    private void DoFoo()
    {
        var sqlite = _app.Container.Resolve<ISQLite>();
    }
}

另一种稍微复杂的方法是使用 ServiceLocator 模式。您可能会遇到类似以下内容:

public static class Locator
{
    private static Func<Type, object> _resolver;

    public static T ResolveService<T>() => 
        (T)_resolver?.Invoke(typeof(T));

    public static void SetResolver(Func<Type, object> resolver) => 
        _resolver = resolver;
}

在您的应用程序中,您只需设置解析器即可。 Prism 实际上使用 ViewModel 定位器执行类似的操作,然后允许它注入 NavigationService 的正确实例。

public class App : PrismApplication
{
    protected override void OnInitialized()
    {
        SetServiceLocator();
        NavigationService.NavigateAsync("MainPage");
    }

    protected override void RegisterTypes()
    {
        // RegisterTypes
    }

    private void SetServiceLocator()
    {
        Locator.SetResolver(type => Container.Resolve(type, true));
    }
}

最后,您的服务将简单地引用服务定位器,例如:

public class BarBackgroundService
{
    public void DoBar()
    {
        var sqlite = Locator.ResolveService<ISQLite>();
        // do foo
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 Prism 在 Xamarin Forms 的后台服务中实现依赖注入 的相关文章

随机推荐

  • 如何向正在运行的 Linux 进程发送 Ctrl-Break?

    我正在调试在 Sun 的 JDK 1 4 2 18 上运行的应用程序中的内存泄漏 该版本似乎支持命令行参数 XX HeapDumpOnCtrlBreak 这可能会导致 JVM 在遇到控制中断时转储堆 如何将其发送到 Linux 机器上的后台
  • EnumChildWindows 还是 FindWindowEx?

    我可以选择使用 API EnumChildWindows 或 FindWindowEx 中的任何一个 有什么建议哪个 api 更注重性能 FindWindowEx 内部是否使用 EnumChildWindows 来获取特定窗口的句柄 这实际
  • 联合元素对齐

    如果我有一个联合 C 标准保证联合本身将与最大元素的大小对齐 union U long l int i short s char c 2 u 但对于工会内部各个工会成员的协调 它是怎么说的呢 下面的表达式能保证为真吗 u l u i u i
  • C++ STL 下一个排列与组合

    我知道我可以使用std next permutation在包含元素的某些容器上 1 2 3 这将生成该序列的 6 种排列 我想做的是给定一些设置 1 2 3 4 5 6 生成大小为 3 的所有可能的排列 因此对于这个例子 4 3 2 将是由
  • 如何在主活动中注册接收者? [复制]

    这个问题在这里已经有答案了 我有一个SmsReceiver我想在主活动中注册的类 我到底应该做什么 我是安卓新手 你可以做两件事 创建和定义BroadcastReceiver in the Manifest 创建并注册BroadcastRe
  • 获取 $_SERVER['AUTH_USER'] 的空白值

    我有一个在 Windows 2008 Server R2 上运行的 PHP 应用程序 它使用 PHP 的 LDAP 库根据 Active Directory 对用户进行身份验证 As per 这个答案 https stackoverflow
  • OCaml:如何运行包含库的脚本

    我正在按照 Real World OCaml 一书来学习 OCaml 许多程序都需要使用 Jane Street Core 库 当我在顶层使用这个核心库中的函数时 它工作得很好 在那里 我只需使用以下命令来打开 Core 库 use top
  • YouTube iframe 不响应 postMessage 命令

    我正在尝试使用来自父级的 postMessage 命令来控制 YouTube iframe 但它似乎不起作用 由于多种原因 我没有使用 YouTube API 只是使用带有 YouTube 嵌入视频的普通 iframe 我尝试发送命令的方式
  • monodevelop 2.1+ 支持 Visual Studio 2010 项目文件吗?

    monodevelop 2 1 是否支持 Visual Studio 2010 项目文件 但是 如果不支持 有人知道计划何时提供支持吗 我问的原因是我有一个在 VS2008 和 Monodevelop 中都使用的解决方案 当我在 2010
  • 为什么 reposync 没有签出我在清单文件中指定的分支?

    假设我有以下清单文件repo https source android com setup develop repo tool MCVE https stackoverflow com help minimal reproducible e
  • 如何通过父进程杀死子进程?

    我使用创建一个子进程fork 如果子进程无法在30秒内完成执行 父进程如何杀死子进程 我想让子进程最多执行 30 秒 如果超过30秒 父进程就会杀死它 你有想法这样做吗 向其发送 SIGTERM 或 SIGKILL http en wiki
  • Dropzone.js 和每个文件的完整路径

    我正在尝试使用 Dropzone js 重新创建删除的文件 文件夹的文件夹结构 有没有办法访问每个文件的完整路径 以便可以在 php 端重新创建目录结构 这是一种简单的方法 您可以额外发送某些文件夹中所有文件的完整路径 dropzone o
  • Xgboost:bst.best_score、bst.best_iteration 和 bst.best_ntree_limit 有什么区别?

    当我使用 xgboost 训练我的数据时2 cates classification problem 我想使用提前停止来获得最佳模型 但我对在预测中使用哪一个模型感到困惑 因为提前停止将返回 3 个不同的选择 例如 我应该使用 preds
  • 读写文本文件的最佳方法

    我正在使用最新版本的 Lazarus IDE 并且我有一个Memo1在我的 TForm1 上 我必须加载一个文本文件Memo1然后编辑备忘录的每一行 我使用Memo1 Lines Strings i 最后 我必须将编辑后的备忘录保存在特定路
  • 对浮点数求反总是安全的吗

    考虑 double f foo double g f where foo 可以返回分配给的任何内容f is double g f 在 C 和 C 中安全吗 对于 IEEE 754 类型 显然是这样 但 C 和 C 并不限制浮点实现 与 Ja
  • 数组向量无法编译[重复]

    这个问题在这里已经有答案了 这个简单的程序 include
  • TreeSet 给出不正确的输出 - Java8

    在处理树集时 我发现了非常奇怪的行为 根据我的理解 以下程序应该打印两行相同的行 public class TestSet static void test String args Set
  • 如何调试 iOS 应用程序在启动时崩溃,仅在程序集文件中设置断点

    我遇到了当前正在开发的应用程序的问题 问题是应用程序在启动时在后台运行一段时间后崩溃 并且仅在这种情况下 在应用程序被杀死时启动应用程序不会导致调试器或手机崩溃 无论是否进行调试 在后台启动应用程序大约 5 10 分钟都不会导致崩溃 在后台
  • 以编程方式设置 Swift 元素的位置

    我在故事板中定义了一个标签 我正在尝试以编程方式更改其位置 SO 上已有一些问题似乎可以解决此问题 但似乎没有一个解决方案有效 即标签不移动 我已经删除了标签上所有现有的限制 但无济于事 我试过了 class LandingViewCont
  • 使用 Prism 在 Xamarin Forms 的后台服务中实现依赖注入

    我在我的 xamarin 表单项目中使用 Prism 我能够在我的视图模型中使用依赖注入 构造函数注入 没有任何问题 我还利用后台服务在后台推送长时间运行的任务 如何做我在后台服务中注入依赖项 当我尝试将接口对象作为参数传递给构造函数 Sy