问题描述
我花了两个多星期的时间搜索google,bing,堆栈溢出和msdn文档,试图弄清楚如何对我正在开发的移动应用程序进行适当的依赖注入.需要明确的是,我每天都在Web应用程序中进行DI.我不需要关于什么,谁以及为什么DI很重要的速成班.我知道这是事实,并且一直在拥抱它.
I have spent over two weeks searching google, bing, stack overflow, and msdn docs trying to figure out how to do a proper dependency injection for a mobile app that I am developing. To be clear, I do DI every day in web apps. I do not need a crash course on what, who, and why DI is important. I know it is, and am always embracing it.
我需要了解的是它在移动应用程序世界中的工作原理,尤其是UWP Template 10移动应用程序.
What I need to understand is how this works in a mobile app world, and in particular a UWP Template 10 Mobile app.
从过去,在.net/Asp应用程序中,我可以"RegisterType(new XYZ).Singleton()等等" {请原谅语法;只是一个示例}.在.netcore中,该方法几乎相同,但进行了一些语法更改.
From my past, in a .net/Asp app I can "RegisterType(new XYZ).Singleton() blah" {please forgive syntax; just an example} in App_Start.ConfigureServices. This works almost identical in .netcore, granted some syntactic changes.
我的问题是,现在我正在尝试提供我的api到需要摘要我的IXYZ服务的UWP应用.我绝不认为他们每次都应该更新"一个实例.必须有一种方法可以将其注入到UWP侧的容器中.而且我觉得我在此过程中缺少了非常一些简单的东西.
My problem is now I am trying to provide my api is going to an UWP app that needs to digest my IXYZ service. By no means do I think that they should "new" up an instance every time. There has to be a way to inject this into a container on the UWP side; and I feel I am missing something very simple in the process.
这是我的代码:
App.xaml.cs
App.xaml.cs
public override async Task OnStartAsync(StartKind startKind, IActivatedEventArgs args)
{
// TODO: add your long-running task here
//if (args.Kind == ActivationKind.LockScreen)
//{
//}
RegisterServices();
await NavigationService.NavigateAsync(typeof(Views.SearchCompanyPage));
}
public static IServiceProvider Container { get; private set; }
private static void RegisterServices()
{
var services = new ServiceCollection();
services.AddSingleton<IXYZ, XYZ>();
Container = services.BuildServiceProvider();
}
MainPage.xaml.cs:
MainPage.xaml.cs:
public MainPage()
{
InitializeComponent();
NavigationCacheMode = NavigationCacheMode.Enabled;
}
MainPageViewModel:
MainPageViewModel:
public class MainPageViewModel : ViewModelBase
{
private readonly IXYZ _xyz;
public MainPageViewModel(IXYZ xyz)
{
//Stuff
_xyz= xyz;
}
}
我现在得到错误: XAML MainPage ... ViewModel类型无法构造.为了用XAML构造,类型不能是抽象的,接口嵌套的泛型或结构,并且必须具有公共的默认构造函数.
I now get the error:XAML MainPage...ViewModel type cannot be constructed. In order to be constructed in XAML, a type cannot be abstract, interface nested generic or a struct, and must have a public default constructor.
我愿意使用任何品牌的IoC容器,但我需要的是一个如何在UWP应用程序中正确使用DI进行服务的示例.关于DI的99.9%的问题与视图(即Prism?)有关,而不仅仅是服务(即DataRepo;又名API/DataService)的简单DI.
I am willing to use any brand of IoC Container, but what I need is an example of how to properly use DI for services in a UWP app. 99.9% of questions about DI is about Views (i.e. Prism?) not just a simple DI for a service (i.e. DataRepo; aka API/DataService).
再次,我觉得我缺少明显的东西,需要向正确的方向轻推.有人可以给我看一个示例项目,基本代码或关于我不应该成为程序员的基础鞭打...请不要这样做(我不知道我的自我是否可以接受).
Again, I feel I am missing something obvious and need a nudge in the right direction. Can somebody show me an example project, basic code, or a base flogging on how I should not be a programmer...please don't do that (I don't know if my ego could take it).
推荐答案
您可以尝试像ASP.NET一样使用Microsoft.Hosting.Extensions,Xamarin.Forms上有一个 James Montemagno ,也可以在我拥有的UWP中使用尝试,它完美地工作.您必须更改某些部分才能使其正常工作.
You can try to Microsoft.Hosting.Extensions just like ASP.NET, there's an implementation on Xamarin.Forms by James Montemagno, as well it can be used in UWP I have tried and it works perfectly. You have to change some parts in order to get it working.
public static class Startup
{
public static IServiceProvider ServiceProvider { get; set; }
public static void Init()
{
StorageFolder LocalFolder = ApplicationData.Current.LocalFolder;
var configFile = ExtractResource("Sales.Client.appsettings.json", LocalFolder.Path);
var host = new HostBuilder()
.ConfigureHostConfiguration(c =>
{
// Tell the host configuration where to file the file (this is required for Xamarin apps)
c.AddCommandLine(new string[] { $"ContentRoot={LocalFolder.Path}" });
//read in the configuration file!
c.AddJsonFile(configFile);
})
.ConfigureServices((c, x) =>
{
// Configure our local services and access the host configuration
ConfigureServices(c, x);
}).
ConfigureLogging(l => l.AddConsole(o =>
{
//setup a console logger and disable colors since they don't have any colors in VS
o.DisableColors = true;
}))
.Build();
//Save our service provider so we can use it later.
ServiceProvider = host.Services;
}
static void ConfigureServices(HostBuilderContext ctx, IServiceCollection services)
{
//ViewModels
services.AddTransient<HomeViewModel>();
services.AddTransient<MainPageViewModel>();
}
static string ExtractResource(string filename, string location)
{
var a = Assembly.GetExecutingAssembly();
using (var resFilestream = a.GetManifestResourceStream(filename))
{
if (resFilestream != null)
{
var full = Path.Combine(location, filename);
using (var stream = File.Create(full))
{
resFilestream.CopyTo(stream);
}
}
}
return Path.Combine(location, filename);
}
}
这篇关于UWP模板10和服务密度注入(MVVM)不是WPF的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!