使用 Prism 在 Xamarin Forms 的后台服务中实现依赖注入
Posted
技术标签:
【中文标题】使用 Prism 在 Xamarin Forms 的后台服务中实现依赖注入【英文标题】:Implement dependency injection in background services in Xamarin Forms using Prism 【发布时间】:2017-12-19 05:20:52 【问题描述】:我在我的 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);
【问题讨论】:
可能在容器有机会注册服务之前调用了 DependencyService.Get不幸的是,Xamarin 和 Xamarin Forms 没有在任何地方提供像 Prism 这样的框架来处理 IoC 场景。不过,有几种方法可以解决这个问题。
首先,Container 是后台服务中 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
【讨论】:
以上是关于使用 Prism 在 Xamarin Forms 的后台服务中实现依赖注入的主要内容,如果未能解决你的问题,请参考以下文章
为啥在使用 Prism 在 Xamarin.Forms 中导航到 root 时,我的 NavigationPage 顶部会出现默认标题?
使用 Prism 在 Xamarin Forms 的后台服务中实现依赖注入
Xamarin.Forms FlyoutPage 不适用于 Prism