Navigation Menu

Skip to content
This repository has been archived by the owner on Oct 27, 2019. It is now read-only.

Need For Independent Standards Implementation #16

Open
XedinUnknown opened this issue Mar 13, 2016 · 10 comments
Open

Need For Independent Standards Implementation #16

XedinUnknown opened this issue Mar 13, 2016 · 10 comments

Comments

@XedinUnknown
Copy link
Contributor

Hi,

Came across your repo because it is listed as standards-compliant in the docs of container-interop/definition-interop. And it's true, this is a fantastic implementation! What can I say, you have my thanks.

However, discovered container-interop because I wanted to make a container implementation-agnostic library that would still use DI. As such, I want to provide default service definitions via a default provider in my lib. This is mainly for 2 reasons:

  1. To ease usage. The user of my library should be able to instantiate my main class, giving it the instance of the container implementation that he prefers, and start benefiting from my lib.
  2. Run unit tests. Can't really determine if critical services are available to my lib without defining them first.

I use your lib for testing, because it's so standards-compliant, and I like it overall. And probably, the users of my lib will use it with your lib, since currently it seems to be the only standards-compliant lib. But hopefully, this will not always be the case, and I absolutely do not wish to limit them in this way.

Currently, I have 3 ways of being flexible through compliance with the container-interop standards:

  1. Create a class for each service, implementing DefinitionInterface. This would really bloat my lib with similar code, and will decrease its maintainability. Additionally, I would have to create a class for each MethodCallInterface whenever I need to perform additional configuration on my services, which is a lot of the times.
  2. Write reusable classes to streamline the process through a convenient API. But you are already doing this in your lib.
  3. Use your lib. This defeats the purpose of what I'm trying to achieve - independence from implementation - so I'm not even considering it.

Right now, I am taking approach 2. However, this creates more opportunity for non-interoperability, which is the opposite of what this whole thing is about. Additionally, like I mentioned before, I'm copying someone else's code mostly (your code).

Wouldn't it be great if there was a separate, standards-compliant, container implementation-agnostic library of convenient wrappers? What I'm suggesting is the extraction of some of your classes, such as MethodCall and ObjectDefinition, into a separate library, which mnapoli/assembly can then depend upon. This way, people like me can provide default service definitions with ease, while still being standards-compliant and container implementation-agnostic. On the other hand, you write that your container implementation is very simple, and anyone who isn't satisfied by it is welcome to write their own. The approach which I am proposing could give them a definition framework to build upon.

What do you think?

@mnapoli
Copy link
Owner

mnapoli commented Mar 13, 2016

Hi @XedinUnknown, the thing is that this repository and definition-interop were part of a project that was experimental, and that has been superseded by https://github.com/container-interop/service-provider now. This new project is also experimental, it's used to try out ideas and we'll bring them back to the PHP-FIG very soon, but I don't consider it stable enough to be used anywhere.

@mnapoli
Copy link
Owner

mnapoli commented Mar 13, 2016

I have added a more explicit warning to the README by the way.

@XedinUnknown
Copy link
Contributor Author

Does this mean that development of Assembly will be discontinued? If not, as an implementation it is still free to include this feature. I could implement this and submit a PR, just would be a shame if it's for nothing =)

@mnapoli
Copy link
Owner

mnapoli commented Mar 13, 2016

I understand. I'm not sure I understood why you couldn't require this library but only use the classes you wanted to (and not use the rest)?

I don't want to add features that are not part of definition-interop. This repository was used and can still be used to test out definition-interop. If we ever add changes to definition-interop they will need to be reflected here, and I don't want to be limited by extra features. By "add changes" it could also mean a complete radical change of the whole classes/project. Keep in mind that this repository can break backward compatibility anytime, you should require 0.2.* to avoid that (BC breaks are only between minor version for 0.* versions).

Also what do you think about the new approach we are taking: https://github.com/container-interop/service-provider ? This isn't more stable though, but it's simpler that's mainly why we went that way.

@XedinUnknown
Copy link
Contributor Author

Got it.

WRT service-provider, I appreciate that this approach is much simpler. However, personally I prefer to go the opposite way: make a complex standard/implementation that defines everything in an as clear as possible way, then provide an API that abstracts all the complexity from the user, but still allows access to it if necessary.
As an example: I like the fact that I can specify method names as service definitions. However, this is much less flexible, and at the same time less solid, than an object of a specifically designated type. Instead, I would provide an abstract implementation of a service provider with a method that is a factory of MethodCallInterface implementations pre-configured to use the instance of DefinitionProviderInterface that generated it.

Then, there's the static nature of the new approach. I would no longer be able to simply provide an instance (or instances) of the service provider to the container, which would run against a DefinitionProviderInterface. To me, having a reference to an instance seems much better, and it is also much easier to work with.

Finally, while a standard configuration format seems like something too complex to start with, it's an excellent idea, but for a separate project. I have a Magento background, and I think that XML configuration is amazing: not only is it expressive and platform-independent, but it is very easy to create intuitive GUIs for them. The definition-interop approach provided a great base for this, having a set of classes that can be easily generated from the XML DOM because they can many times correspond 1 to 1, and everything can be a string.

In conclusion, I absolutely loved definition-interop, and I see many benefits in it over service-provider, while I'm also sure that most of the complexity of definition-interop can be hidden away behind friendly APIs. The question of overhead also doesn't bother me much, since hardware is becoming cheaper every week, while the software that runs our code becomes more intelligent. I believe that the goal of true OOP is to write something that conceptually corresponds to the real world as much as possible. If the real concept is complicated, then maybe the code needs to be too. Just needs to be granular and intuitive, that's all. Which I think is what definition-interop could be with a bit more effort.

@XedinUnknown
Copy link
Contributor Author

Oh, to answer your question: Because I don't want to depend on any concrete implementation of a container.
Additionally, it's a lot of code for nothing. Doesn't feel right. I also develop for WP, and it's best not to ship extra code with plugins.

@mnapoli
Copy link
Owner

mnapoli commented Mar 14, 2016

Got it. FYI the container provided in this package is quite secondary (I wouldn't use it, it's mostly included as a reference or for use in tests), the main goal is to provide implementations of definition-interop.

@XedinUnknown
Copy link
Contributor Author

Yea, for now I'm using it just for tests. But either way, I want the user of my code to be able to choose the container implementation.
However, if I have to rely on any particular implementation, this one is just as good as any other. Only with this approach, there will hopefully be more compatible implementations in the future.

By the way, it doesn't seem too difficult to change the definition format from definition-interop to service-provider in the future, if it becomes the accepted standard.

@XedinUnknown
Copy link
Contributor Author

Another advantage of definition-interop over service-provider, and probably the main one, is that if it gets accepted, a standards-compliant complex implementation is actually possible. Without it, container implementations are forced to be super-simple, which may not be enough for some scenarios.

One way to go around the issue could be to make certain parts of the implementation possible under certain strict conditions, but not required. This could be achieved, for example, by merging the ServiceProvider interface into definition-interop, together with DefinitionProviderInterface. Like this, the user is free to implement definitions in a complicated way or a simple way. A container implementation could support either, or both, and still be standards-compliant.

@mnapoli
Copy link
Owner

mnapoli commented Mar 14, 2016

A standard like this would never happen. If it's too complex, it has no chance of being accepted. That's why simplicity is key.

Also:

Without it, container implementations are forced to be super-simple, which may not be enough for some scenarios.

  • this standard is only meant to be used by modules/bundles, which often have quite simple needs. It's not intended to be used by frameworks or framework users: they are free to use the full features of their container of choice (there is no gain for container-agnostic configuration here)
  • service-provider is actually more permissive than definition-interop: with definition-interop you are limited in what you can do by what's explicitly allowed by the standard. With service-provider you write any PHP code you want to create objects, you have no limitations. So I find service-provider more powerful than definition-interop.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants