Dependency injection 使用Prism在Xamarin表单中的后台服务中实现依赖项注入

Dependency injection 使用Prism在Xamarin表单中的后台服务中实现依赖项注入,dependency-injection,xamarin.forms,prism,background-service,Dependency Injection,Xamarin.forms,Prism,Background Service,我在我的xamarin表单项目中使用Prism。我能够使用依赖注入(构造函数注入)在我的视图模型中没有任何问题。我还利用后台服务在后台推送长时间运行的任务。如何在后台服务中注入依赖关系?当我尝试将接口对象作为参数传递给构造函数(SyncingBackgroundingCode)时,对象(SqliteService)为空。我已在依赖项注入容器中注册并解析了对象。 如何处理这种情况?有人能提供一个例子或链接来实现这种情况吗 这是我试图实现依赖注入的代码片段 This is in Droid :-

我在我的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);
                    }
                }
这在Droid中:-
公共类AndroidSyncBackgroundService:服务
{
取消令牌源;
公共覆盖iBind OnBind(意图)
{
返回null;
}
公共覆盖StartCommandResult OnStartCommand(意图、StartCommandFlags标志、int-startId)
{
_cts=新的CancellationTokenSource();
Task.Run(()=>{
试一试{
//调用共享代码
var oBackground=新同步背景代码();
oBackground.RunBackgroundingCode(_cts.Token).Wait();
}
捕获(操作取消异常)
{
}
最后{
如果(_cts.iscancellationrequest)
{
var消息=新的CanceledTask();
Device.beginInvokeMainThread(
()=>MessagingCenter.Send(消息,“已取消任务”)
);
}
}
},_cts.Token);
返回StartCommandResult.Sticky;
}
公共覆盖无效OnDestroy()
{
如果(_cts!=null){
_cts.Token.ThrowIfCancellationRequested();
_cts.Cancel();
}
base.ondestory();
}
}
这是在PCL中:-
公共类同步背景代码
{
公共SQLiteConnection\u sqlconnection;
SqliteCalls oSQLite=newsqlitecalls();
ISqliteService SqliteService;
公共同步背景代码(ISqliteService SqliteService)
{
//对象为空
}
公共异步任务RunBackgroundingCode(CancellationToken令牌)
{
DependencyService.Get().GetConnection();
等待任务。运行(异步()=>{
token.ThrowIfCancellationRequested();
if(App.oSqliteCallsMainLH!=null)
{                 
App.bRunningBackgroundTask=true;
oSQLite=App.oSqliteCallsMainLH;
等待任务。运行(异步()=>
{
等待任务。延迟(1);
ftnSaveOnlineModeXMLFormat(“脱机”,0);
oSQLite.SyncEmployeeTableData();
oSQLite.SaveOfflineAppCommentData();
oSQLite.SaveOfflineAdditionToFlowData();
等待任务。延迟(500);
var msgStopSyncBackgroundingTask=new StopSyncBackgroundingTask();
发送(msgStopSyncBackgroundingTask,“停止同步BackgroundingTask”);
});
}
},代币);
}
}

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

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

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

    private void DoFoo()
    {
        var sqlite = _app.Container.Resolve<ISQLite>();
    }
}
最后,您的服务只需引用服务定位器,如:

public class BarBackgroundService
{
    public void DoBar()
    {
        var sqlite = Locator.ResolveService<ISQLite>();
        // do foo
    }
}
公共类BarBackgroundService
{
公共无效多巴()
{
var sqlite=Locator.ResolveService();
//多福
}
}

可能在容器有机会注册服务之前调用了DependencyService.Get()。确保它们以正确的顺序被触发。否则,我看不出有任何理由不解决服务问题。另外,最好在程序集上使用[assembly:Dependency(typeof(SQLitService))]注册服务,这样可以确保在代码有机会解析之前始终注册服务。
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
    }
}