Intellisense for WithConstructorArgument. What do you think?

89 views
Skip to first unread message

Remo Gloor

unread,
Feb 24, 2011, 12:42:32 PM2/24/11
to ninject
Hi Everyone,

I had the idea to add intellisense support for Constructor Arguments
and constructor selection without adding the Inject attribute. But
before I start the implementation I want some feedback and improvments
from the community. Furthermore, this won't get one of the current
high priority tasks either as there are more important thing on the
list at the moment.

I planned to add the following syntax. The used method and class names
are examples and need to be discussed as I'm not yet happy about them
myself.

e.g. For ctor Foo(int x, IBar bar) you can specify
.Bind<Foo>().ToSelf().UsingCtor(() => new X(3, Let.Inject<IBar>())

Note: The lambda expression will never by executed! It's just a
definition of which constructor is used and with parameters are
passed. In short this specifies three things:
1. The constructor that will be used for the binding
2. That the first argument is 3
3. That the second argument is injected

I thought about adding a similar thing for properties too:
.Bind<Foo>().ToSelf().WithPropertyValue(foo => foo.X = 3)
.Bind<Foo>().ToSelf().WithPropertyValue(foo => foo.Bar =
Let.Inject<IBar>())

But don't we have this already?
.Bind<Foo>().ToSelf().OnActivation(foo => foo.Bar = 3)
.Bind<Foo>().ToSelf().OnActivation((ctx, foo) => foo.Bar =
ctx.Kernel.Get<IBar>())

What do you think about such a change in the syntax? Are there any
better ways how to do this? Have you better names for the method/class
names above? Any feedback is appreciated!

- Remo

Urs Enzler

unread,
Feb 25, 2011, 11:20:34 AM2/25/11
to ninject

Hi Remo

I like the idea on constructor arguments because that would remove the
magic strings we need in the current version.
Maybe the Let.Inject is a bit too verbose, but no better idea right
away from my side.

Regarding the properties, I wouldn't introduce this because this would
lead to mixing construction with runtime behavior. I prefer using
OnActivation for now.

Cheers Urs

LOBOMINATOR

unread,
Feb 25, 2011, 11:37:21 AM2/25/11
to nin...@googlegroups.com
Hy urs

Remo and I first discussed passing null or default(t). But this is also a valid case for constants passing into the ctor. Therefore we need to differentiate this case. The let construct or a similar construct gives us the possibility to either define constants, null, defauls or let ninject inject the dependency. What also would be possible with this approach the let the user define stuff like

.Bind<Foo>().ToSelf().UsingCtor(() => new X(3, Let.Inject<IBar>(), MagicValueRetrievalMethodWithArgument(blub))

We did spike this approach yesterday and it worked like a charm

Daniel

> --
> You received this message because you are subscribed to the Google Groups "ninject" group.
> To post to this group, send email to nin...@googlegroups.com.
> To unsubscribe from this group, send email to ninject+u...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/ninject?hl=en.
>

a.loker

unread,
Mar 2, 2011, 6:07:50 AM3/2/11
to ninject
To get rid of Let, one could pass an argument to the expression like:

.UsingCtor( arg => new X(3, arg.Inject<IBar>())

Instead of Inject, what about
- T One<T>()
- IEnumerable<T> Many<T>()
- T[] ArrayOf<T>()
so one could say:

.UsingCtor( get => new HavingSingleDependency(get.One<IBar>())
.UsingCtor( get => new HavingEnumerableDependency(get.Many<IBar>())
.UsingCtor( get => new HavingArrayOfDependencies(get.ArrayOf<IBar>())

I don't know if it's really better, but at least it can be given any
name you like. Just an idea.

Regards,
Andre

On 25 Feb., 17:37, LOBOMINATOR <lobomina...@gmx.ch> wrote:
> Hy urs
>
> Remo and I first discussed passing null or default(t). But this is also a valid case for constants passing into the ctor. Therefore we need to differentiate this case. The let construct or a similar construct gives us the possibility to either define constants, null, defauls or let ninject inject the dependency. What also would be possible with this approach the let the user define stuff like
>
> .Bind<Foo>().ToSelf().UsingCtor(() => new X(3, Let.Inject<IBar>(), MagicValueRetrievalMethodWithArgument(blub))
>
> We did spike this approach yesterday and it worked like a charm
>
> Daniel
>

a.loker

unread,
Mar 2, 2011, 6:09:36 AM3/2/11
to ninject
with instead of get doesn't look bad either:

UsingCtor(with => new Impl(with.One<IDisposable>()));
UsingCtor(with => new Impl(with.Many<IDisposable>()));
UsingCtor(with => new Impl(with.ArrayOf<IDisposable>()));

LOBOMINATOR

unread,
Mar 2, 2011, 9:42:18 AM3/2/11
to nin...@googlegroups.com
Hy Andre,

The problem with this approach is in my opinion that the user of the API
needs to know whether to use Many, ArrayOf etc. With one generic Let the
user only needs to define the generic of the specific ctor argument
therefore instead of:

> .UsingCtor( get => new HavingSingleDependency(get.One<IBar>())
> .UsingCtor( get => new HavingEnumerableDependency(get.Many<IBar>())
> .UsingCtor( get => new HavingArrayOfDependencies(get.ArrayOf<IBar>())

He would do:

> .UsingCtor( get => new HavingSingleDependency(Let.Inject<IBar>())
> .UsingCtor( get => new
HavingEnumerableDependency(Let.Inject<IEnumerable<IBar>>())
> .UsingCtor( get => new
HavingArrayOfDependencies(Let.Inject<Array<IBar>>())

Daniel

Urs Enzler

unread,
Mar 2, 2011, 3:51:54 PM3/2/11
to ninject
I like the idea to use a parameter to get rid of the Let construct.
But I would only support

UsingConstructor(do => new Impl(do.Inject<T>()))

Cheers
Urs
Reply all
Reply to author
Forward
0 new messages