.net core Prism能否使用.NET Core';什么是内置依赖注入?

.net core Prism能否使用.NET Core';什么是内置依赖注入?,.net-core,prism,.net Core,Prism,我想使用.NET Core 3.1启动一个WPF应用程序 Prism是否可以使用.NETCore的内置DI(IServiceCollection),或者我是否必须使用Unity之类的工具? 如果Prism不能使用内置DI,它们可以并排存在吗 我必须使用像Unity这样的东西吗 ServiceCollection是“类似于统一的东西”。是的,您可以将其与prism一起使用: 创建一个IContainerExtension实现,该实现重定向到ServiceCollection 从prismaplic

我想使用.NET Core 3.1启动一个WPF应用程序
Prism是否可以使用.NETCore的内置DI(
IServiceCollection
),或者我是否必须使用Unity之类的工具?
如果Prism不能使用内置DI,它们可以并排存在吗

我必须使用像Unity这样的东西吗

ServiceCollection
是“类似于统一的东西”。是的,您可以将其与prism一起使用:

  • 创建一个
    IContainerExtension
    实现,该实现重定向到
    ServiceCollection
  • prismaplicationbase
    派生并从
    CreateContainerExtension
  • Prism可以利用.Net内核的内置DI吗

    从我所看到的情况来看,你不能用ASP.NET核心内置软件代替Prism的DryIot。主要来说,DryIot的功能比ServiceCollection API更全面。我发现这个开源软件有一个使用
    servicecolection
    IContainerExtension
    实现,但按照开发人员自己的话来说,这更多的是一个概念证明,而不是一个可行的解决方案

    如果Prism不能使用内置DI,它们可以并排存在吗

    是的,他们可以。需要注意的是,您不能简单地在
    servicecolection
    中注册服务,并期望能够将该服务直接注入到您的应用程序、模块和ViewModels中。这将失败,因为这些文件由Prism框架管理,因此注入将仅适用于使用
    IContainerRegistry
    接口注册的服务

    利益 你为什么要这么做?作为内置物联网容器,
    ServiceCollection
    API是众所周知的,因此对于.Net开发人员来说,它将更简单。此外,您可以构造非WPF项目,以使用默认容器注册服务,从而允许它们与桌面项目完全解耦。这对于更复杂的体系结构(如域驱动设计)非常有用

    让我们考虑下面的项目结构:

    solution
    -- Desktop // Prism WPF application, containing only views and models
    -- Application // Class library, containing operational logic.
    
    假设作为应用程序项目的一部分,您需要一个
    IUserService
    ,它保存当前用户的信息,当用户在桌面应用程序中进行身份验证时,必须在内存中填充这些信息。注册方法如下所示:

    public IServiceCollection AddServices(this IServiceCollection services)
    {
        services.AddSingleton<IUserService, UserService>()
    }
    
  • 将IServiceProvider注入您需要的
    IUserService
    位置。在本例中,我将使用棱镜模块:

     public class Module : IModule
     {
         private readonly IUserService userService;
    
         public Module(IServiceProvider serviceProvider)
         {
             this.userService = serviceProvider.GetService<IUserService>();
         }
         ...
         private void Authenticate()
         {
             this.userService.IsAuthenticated = true;
         }
     }
    
  • 这里最棘手的部分是工厂。为了更好地理解服务注册中的工厂,请知道有时您可能需要访问其他服务以提供正确的实现实例。例如,如果注册了
    IHttpClient
    ,则需要为
    iAuthorizationService
    提供
    HttpAuthorizationService
    实现,而不是
    DesktopAuthorizationService

    本质上,我们用一个与DryIot兼容的工厂(接受DryIot容器的实例)包装原始工厂方法,该工厂可以为原始工厂提供
    IServiceProvider
    实例

  • 参考
    Microsoft.Extensions.DependencyInjection

  • 在应用程序中调用您的服务注册方法:

     protected override void RegisterTypes(IContainerRegistry container)
     {
         // Build service provider using the ServiceCollection API
         var provider = new ServiceCollection()
             .AddServices()
             .BuildServiceProvider();
    
         // Register IServiceProvider within DryIot and provide 
         // a factory method to retrieve the service instance
         container.Register<IServiceProvider>(() => provider);
     }
    
     protected override void RegisterTypes(IContainerRegistry container)
     {
         var services = new ServiceCollection().AddServices()
    
         foreach (var service in services)
         {
             Adapter.Register(container, service);
         }
     }
    
  • 直接在模块构造函数中注入
    IUserService

     public class Module : IModule
     {
         private readonly IUserService userService;
    
         public Module(IUserService userService)
         {
             this.userService = userService;
         }
     }
    
  • 最后的想法 我再次推荐简单的方法。简单意味着更低的学习曲线和更少的出错空间。相比之下,不便是微不足道的

    另一个合理的警告-这不是生产就绪代码。尤其是无seemle方法。我还没有对这个实现进行“战斗测试”,但它可能会为您指明正确的方向

    如果有人有反馈/意见,我很乐意阅读:)

    Prism可以利用.Net内核的内置DI吗

    简短回答,

    这里是@brianlagunas(Prism的创建者)

    正如我提到的,我们不能使用IServiceProvider,因为我们在NetStandard1.0中。ServiceProvider和IServiceCollection在netstandard 2.0中。另外,Prism需要的许多功能在iSeries的eCollection实现中受到限制。例如命名实例和注册,以及可变容器

    这里是@dansiegel

    我花了很多时间讨论这个问题,最终我们不能直接依赖IServiceProvider和IServiceCollection,原因很多,超出了它们是否可用的范围

    这是同样由 @布里安拉古纳斯

     public class Module : IModule
     {
         private readonly IUserService userService;
    
         public Module(IUserService userService)
         {
             this.userService = userService;
         }
     }