为什么要使用服务(IServiceProvider的)? [英] Why use services (IServiceProvider)?

查看:5503
本文介绍了为什么要使用服务(IServiceProvider的)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我来这个问题,从探索XNA框架,但我想一个大致的了解。

I'm coming to this question from exploring the XNA framework, but I'd like a general understanding.

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



,然后我们做任何功能/特性在界面的内容:

and then we do something with whatever functions/properties are in the interface:

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



我试图找出原因这种实现是任何优于:

I'm trying to figure out why this kind of implementation is any better than:

myObject = InstanceFromComponentThatWouldProvideTheService();

myObject.DoSomething();

当您使用的服务方式让您的界面,你真的刚开的一个实例组件反正提供服务。对?你不能有一个接口实例。而且也只有一个类可以是服务的提供者。因此,所有你真的是你的组件类的一个实例,唯一的区别是你只能访问组件对象的一个​​子集(无论子集的接口)。

When you use the services way to get your interface, you're really just getting an instance of the component that provides the service anyway. Right? You can't have an interface "instance". And there's only one class that can be the provider of a service. So all you really have is an instance of your component class, with the only difference being that you only have access to a subset of the component object (whatever subset is in the interface).

这是如何从仅仅有公共和私有的方法和属性有什么不同?换句话说,该组件的公共方法/属性的的接口,我们可以用这一切迂回停止。你仍然可以改变你如何实现一个接口不破坏任何东西(除非您更改方法签名,但将打破服务实现过)。

How is this any different from just having public and private methods and properties? In other words, the public methods/properties of the component is the "interface", and we can stop with all this roundaboutness. You can still change how you implement that "interface" without breaking anything (until you change the method signature, but that would break the services implementation too).

和有将是组件,反正服务之间的1对1的关系(不止一个类不能注册成为该服务的提供者),我看不出一类是多个提供商服务(SRP和所有)。

And there is going to be a 1-to-1 relationship between the component and the service anyway (more than one class can't register to be a provider of the service), and I can't see a class being a provider of more than one service (srp and all that).

所以我想我试图找出哪些问题这种架构是为了解决。 ?我想什么

So I guess I'm trying to figure out what problem this kind of framework is meant to solve. What am I missing?

推荐答案

请允许我通过从XNA本身就是一个例子解释:

Allow me to explain it via an example from XNA itself:

ContentManager 构造函数采用的IServiceProvider 。然后,它使用了的IServiceProvider 获得 IGraphicsDeviceService ,它反过来使用获得 GraphicsDevice的在其上加载的东西像纹理,效果等。

The ContentManager constructor takes a IServiceProvider. It then uses that IServiceProvider to get a IGraphicsDeviceService, which it in turn uses to get a GraphicsDevice onto which it loads things like textures, effects, etc.

它不能采取游戏 - 因为这类完全是可选的(并且在一个从属组件)。它不能采取 GraphicsDeviceManager (常用实施 IGraphicsDeviceService ),因为,像游戏是设置了的GraphicsDevice

It cannot take a Game - because that class is entirely optional (and is in a dependent assembly). It cannot take a GraphicsDeviceManager (the commonly used implementation of IGraphicsDeviceService) because that, like Game is an optional helper class for setting up the GraphicsDevice.

这不可能一个可选的辅助类采取的GraphicsDevice 直接,因为你可能会创建一个 ContentManager 的GraphicsDevice 创建(这是的究竟的默认游戏类做什么)。因此,需要,它可以从的之后

It can't take a GraphicsDevice directly, because you may be creating a ContentManager before the GraphicsDevice is created (this is exactly what the default Game class does). So it takes a service that it can retrieve a graphics device from later.

现在,这里是真正的踢球者检索图形设备服务:它的可能的拍摄 IGraphicsDeviceService 和使用直接。的的:如果在某个时候在今后的XNA团队增加(例如)一些内容类型依赖于一个 AudioDevice 类?然后,你就必须修改 ContentManager 构造函数的方法签名采取 IAudioDeviceService 或东西 - 这将打破第三方的代码。 。通过让你避免这个问题,服务提供商

Now here is the real kicker: It could take a IGraphicsDeviceService and use that directly. BUT: what if at some time in the future the XNA team adds (for example) an AudioDevice class that some content types depend on? Then you'd have to modify the method signature of the ContentManager constructor to take an IAudioDeviceService or something - which will break third-party code. By having a service provider you avoid this issue.

在的事实 - 你不必等待XNA球队需要增加公共资源新的内容类型:当你编写自定义的 ContentTypeReader 则可以从内容管理器可以访问到的IServiceProvider 和查询它的的任何服务你喜欢的 - 甚至是你自己!这样,你的自定义内容类型可以使用相同的机制,一流的XNA图形类型使用,而不必知道他们或他们需要的服务XNA代码。

In fact - you don't have to wait for the XNA team to add new content types requiring common resources: When you write a custom ContentTypeReader you can get access to the IServiceProvider from the content manager and query it for whatever service you like - even your own! This way your custom content types can use the same mechanism as the first-class XNA graphics types use, without the XNA code having to know about them or the services they require.

(相反,如果你从来没有加载图形类型与 ContentManager ,那么你永远不必为它提供一个图形设备的服务。)

(Conversely, if you never load graphics types with your ContentManager, then you never have to provide it with a graphics device service.)

这是当然的,一切都很好了 XNA一样,这需要在不破坏第三方代码更新。尤其是对于像 ContentManager 是由第三方扩展的

This is, of course, all well and good for a library like XNA, which needs to be updatable without breaking third-party code. Especially for something like ContentManager that is extendible by third parties.

但是:我看到很多使用跑来跑去的人 DrawableGameComponent ,发现你不能得到共享 SpriteBatch 进入很容易,和所以建立某种精灵批量服务的人们围绕通过。这比你需要的游戏,通常没有版本控制,装配的依赖,或第三方的可扩展性要求,担心有更多的并发症。仅仅因为 Game.Services 存在,并不意味着你必须使用它!如果你的可以的传递的东西(如 SpriteBatch 实例)围绕直接 - 只要做到这一点 - 这是更简单,更明显

However: I see lots of people running around using DrawableGameComponent, finding that you can't get a shared SpriteBatch into it easily, and so creating some kind of sprite-batch-service to pass that around. This is a lot more complication than you need for a game which generally has no versioning, assembly-dependency, or third-party extensibility requirements to worry about. Just because Game.Services exists, doesn't mean you have to use it! If you can pass things (like a SpriteBatch instance) around directly - just do that - it's much simpler and more obvious.

这篇关于为什么要使用服务(IServiceProvider的)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆