tschneidereit / SwiftSuspenders

NOTE: Find the offical repo at http://github.com/robotlegs/swiftsuspenders
https://github.com/robotlegs/swiftsuspenders
MIT License
280 stars 89 forks source link

External Injection Point Configuration - XML or new syntax #32

Closed darscan closed 12 years ago

darscan commented 13 years ago

With the discovery that annotations/metadata can indeed be used in Flash Professional (by selecting "Export SWC" under publish settings) the XML configuration of injection points seems less useful.

On the other hand being able to configure injection points externally could be useful for integration with external libraries or cases where modifying classes (to add metadata) is impossible/undesirable.

As far as I can tell though, currently the XML needs to be provided when constructing the container - which might not be very convenient. It might be worth expanding the API to allow for external configuration of injection points at runtime. Thoughts?

tschneidereit commented 13 years ago

Mmh, that's an interesting idea.

Do you think that it should be possible to append injection point configs during runtime or would it suffice to switch out the entire XML config table?

The latter would be trivial to implement, the former at least a little bit of work. Not really much, though.

darscan commented 13 years ago

Swapping out the whole XML config table seems less useful - one would have to know the entire config in order to modify/append points.

darscan commented 13 years ago

My thinking is that this would be a v2 type feature - possibly replacing the current XML config scheme.

tschneidereit commented 13 years ago

Right, so appending configs it is.

I don't think it'd be wise to enable removal of individual configs, though. Doing so would make working with XML configs a lot more flexible and thus unpredictable than doing the same with metadata.

darscan commented 13 years ago

Indeed!

tschneidereit commented 13 years ago

I agree: Makes sense to break compatibility with the current XML config stuff for this.

I also don't think that v2 should necessarily be too far off: I'd really like to clean up the API a bit.

That opens up a bag of worms regarding Robotlegs and DI container pluggability, though. Will bring that up on the mailing list soonish.

Glidias commented 13 years ago

Haxe-compiled classes don't support metadata annotations, so XML configuration can come in useful for that. Unfortunately, using XML configuration prevents regular metadata from being used either, so actually a coded solution may be better (and stronger too with better reflection checking at runtime unlike writing a XML file and losing the possibility of running with both methods.)

tschneidereit commented 13 years ago

Thanks for bringing that up - it's something I investigated myself some time ago.

From the following commit it looks like Nicholas is working on adding metadata support to Haxe, though: http://code.google.com/p/haxe/source/detail?r=3191

It's certainly on the list of planned features: http://haxe.org/com/features

Nevertheless, I agree that making XML and metadata based configuration play nice with each other is desirable. I will make sure to keep that in mind when designing the new configuration API.

darscan commented 12 years ago

So, this is what I was trying to say at T{H}:

There are two sides to the coin:

A. map(Type).toProvider()

This explains what to do when queried for a type+name.

B. [Inject], [PostConstruct]

These declare injection points. But they do so internally and require reflection. It would be good if we could configure the points for a given class manually and externally. For example:

injector.configure(Class)
  .addInjectionPoint('fieldName').usingProvider(type, name=null);

injector.configure(Class)
  .addInjectionPoint('url').usingValue('http://api.myapp.com');

injector.configure(Class)
  .addConstructorArgument().useProviderFor(type, name=null);

injector.configure(Class)
  .mapPostConstructPoint('methodName').toProviderFor(type, name=null);

Obviously, it needs a better fluent interface than I've supplied.

tschneidereit commented 12 years ago

Thanks for getting back to this. I've been meaning to add an API along those lines, but didn't yet get around to it.

Maybe a DSL with nested instances works better here, though:

injector.configure(Class) .add(new FieldInjectionPoint('fieldName', type, name=null).optional())

The reason being that the various injection points require somewhat different configuration options.

But yeah: Finding a good DSL for this isn't easy. But then, it never is.

darscan commented 12 years ago

Yeh, that's much nicer :)

tschneidereit commented 12 years ago

Cool. I'll add something along those lines before the final release and run it by you.

squeedee commented 12 years ago

I don't see a 'watch' for issues so I'll just +1 here so I get notifications. I'd like to see this for Boiler.