gpt4 book ai didi

c# - 为什么要使用服务(IServiceProvider)?

转载 作者:可可西里 更新时间:2023-11-01 02:59:42 38 4
gpt4 key购买 nike

我是在探索 XNA 框架时提出这个问题的,但我希望有一个大致的了解。

ISomeService someService = (ISomeService)Game.GetServices(typeof(ISomeService));

然后我们用接口(interface)中的任何函数/属性做一些事情:

someService.DoSomething();  // let's say not a static method but doesn't matter

我想弄清楚为什么这种实现比:

myObject = InstanceFromComponentThatWouldProvideTheService();

myObject.DoSomething();

当您使用服务方式获取接口(interface)时,您实际上只是获取提供服务的组件实例。正确的?你不能有一个接口(interface)“实例”。而且只有一个类可以作为服务的提供者。因此,您真正拥有的只是组件类的一个实例,唯一的区别是您只能访问组件对象的一个​​子集(接口(interface)中的任何子集)。

这与仅具有公共(public)和私有(private)方法和属性有何不同?换句话说,组件的公共(public)方法/属性“接口(interface)”,我们可以停止所有这种迂回。您仍然可以在不破坏任何东西的情况下更改实现该“接口(interface)”的方式(直到您更改方法签名,但这也会破坏服务实现)。

无论如何,组件和服务之间将是一对一的关系(不能有多个类注册成为服务的提供者),而且我看不到一个类被提供不止一项服务(srp 等等)。

所以我想我是想弄清楚这种框架要解决什么问题。我错过了什么?

最佳答案

请允许我通过 XNA 本身的示例来解释它:

ContentManager 构造函数采用 IServiceProvider。然后,它使用该 IServiceProvider 获取 IGraphicsDeviceService,然后使用该服务获取 GraphicsDevice,并在其上加载纹理、效果等内容,等

它不能采用 Game - 因为该类完全是可选的(并且在依赖程序集中)。它不能采用 GraphicsDeviceManager(IGraphicsDeviceService 的常用实现),因为像 Game 一样,它是一个可选的辅助类,用于设置 >图形设备

它不能直接获取 GraphicsDevice,因为您可能会在创建 GraphicsDevice 之前创建一个 ContentManager(这是 正是默认的 Game 类所做的)。所以它需要一个服务,它可以稍后检索图形设备。

现在真正的关键在于:可以采用IGraphicsDeviceService 并直接使用它。 但是:如果在未来的某个时间 XNA 团队添加(例如)某些内容类型所依赖的 AudioDevice 类会怎么样?然后,您必须修改 ContentManager 构造函数的方法签名以获取 IAudioDeviceService 或其他内容 - 这将破坏第三方代码。通过服务提供商,您可以避免这个问题。

事实上 - 您不必等待 XNA 团队添加需要公共(public)资源的新内容类型:当您编写自定义 ContentTypeReader 时,您可以访问 IServiceProvider 来自内容管理器并查询它以获取您喜欢的任何服务 - 甚至是您自己的!通过这种方式,您的自定义内容类型可以使用与一流 XNA 图形类型相同的机制,而 XNA 代码无需了解它们或它们所需的服务。

(相反,如果您从不使用 ContentManager 加载图形类型,那么您永远不必为其提供图形设备服务。)

当然,对于像 XNA 这样的,这一切都很好,它需要在不破坏第三方代码的情况下进行更新。特别是对于像 ContentManager 这样可由第三方扩展的东西。

但是:我看到很多人在使用 DrawableGameComponent 时四处奔波,发现您无法轻松地将共享的 SpriteBatch 放入其中,因此创建某种 Sprite 批处理服务来传递它。这比您通常不需要担心版本控制、程序集依赖性或第三方可扩展性要求的游戏要复杂得多。仅仅因为 Game.Services 存在,并不意味着您必须使用它!如果您可以直接传递东西(比如 SpriteBatch 实例)——就这么做——它会更简单、更明显。

关于c# - 为什么要使用服务(IServiceProvider)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6802090/

38 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com