Re: Suggestion: make resolution order configurable

75 views
Skip to first unread message

TWischmeier

unread,
Apr 6, 2010, 8:43:10 AM4/6/10
to ninject-dev
To give a follow up on this:

Since changing the source code of Ninject to match my needs everytime
a new version comes out is a very bad practice, I again looked through
the code to see if there is any virtual method which I could make use
of. I found one in KernelBase. So, as I already was using my own
Kernel which inherited from StandardKernel, I just needed to add one
single method:

public override IEnumerable<IBinding> GetBindings(Type service)
{
return base.GetBindings(service).Reverse();
}

This seems to do the trick. When I run the unit tests, there are some
that fail when assumptions about the resolution order are being made
(obivously). I only updated the tests for late activation in
IEnumerable, that test then passed, so I assume that this change will
work as intended for me.

Ian Davis

unread,
Apr 6, 2010, 1:46:20 PM4/6/10
to ninje...@googlegroups.com
What is the context of this post? I don't recall what you are responding to.

Thanks,

Ian


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


TWischmeier

unread,
Apr 7, 2010, 2:30:34 AM4/7/10
to ninject-dev
It seems Google did not append my message to the corresponding
discussion properly, I was responding to this thread:

http://groups.google.com/group/ninject-dev/browse_thread/thread/528933cb00df6f97

(basically being able to re-define bindings).

To update on this again, the overloaded behavior to GetBindings()
seems to not work as I expected, but I haven't figured out yet what
exactly the problem is. If I re-define an existing binding, I am not
getting a resolution at all. Today I do not have time to investigate
further, but hopefully I will be able to do so on Friday.

On 6 Apr., 19:46, Ian Davis <ida...@innovatian.com> wrote:
> What is the context of this post? I don't recall what you are responding to.
>
> Thanks,
>
> Ian
>
> On Tue, Apr 6, 2010 at 5:43 AM, TWischmeier

> <tim.wischme...@googlemail.com>wrote:


>
> > To give a follow up on this:
>
> > Since changing the source code of Ninject to match my needs everytime
> > a new version comes out is a very bad practice, I again looked through
> > the code to see if there is any virtual method which I could make use
> > of. I found one in KernelBase. So, as I already was using my own
> > Kernel which inherited from StandardKernel, I just needed to add one
> > single method:
>
> > public override IEnumerable<IBinding> GetBindings(Type service)
> > {
> >  return base.GetBindings(service).Reverse();
> > }
>
> > This seems to do the trick. When I run the unit tests, there are some
> > that fail when assumptions about the resolution order are being made
> > (obivously). I only updated the tests for late activation in
> > IEnumerable, that test then passed, so I assume that this change will
> > work as intended for me.
>
> > --
> > You received this message because you are subscribed to the Google Groups
> > "ninject-dev" group.
> > To post to this group, send email to ninje...@googlegroups.com.
> > To unsubscribe from this group, send email to

> > ninject-dev...@googlegroups.com<ninject-dev%2Bunsu...@googlegroups.com>

Ian Davis

unread,
Apr 8, 2010, 11:18:46 AM4/8/10
to ninje...@googlegroups.com
So, you would like to do something like, 

Bind<T>().To<U>().InOrder(3);
Bind<T>().To<R>().InOrder(1);
Bind<T>().To<C>().InOrder(2);

Am I understanding correctly? If not syntactically, then conceptually?

-Ian


To unsubscribe from this group, send email to ninject-dev...@googlegroups.com.

Nate Kohari

unread,
Apr 8, 2010, 11:36:34 AM4/8/10
to ninje...@googlegroups.com
The resolution order should match the order in which the bindings are registered. Maybe I'm missing something, but couldn't you just change the order of your bindings?

-Nate

TWischmeier

unread,
Apr 9, 2010, 3:11:45 AM4/9/10
to ninject-dev
Unfortunately I cannot (without much effort) change the binding order
in my application. For a short explanation: I designed something like
component inheritance. So you can inherit from a component (which
basically is a ninject module) and if you want to replace a part of
what it already has configured, you replace (or better: define again)
the binding. It works quite good, and it worked with the pre-relase
version of Ninject 2 where I adjusted just a few lines in
Ninject.Syntax.ResolutionExtensions to return LastOrDefault instead
FirstOrDefault.

So syntactically I want to do:
Rebind<IService>().To<ADifferentImplementationThanInitially>().Named("xxx");

But the Rebind command does not behave the way I need it, because it
drops all bindings to IService. I have multiple bindings to the same
service which are distinguished by their name. So I think I may very
well be using Ninject in a manner it wasn't designed for, but I really
hope I can "bend it to my will", because it has worked like a charme
before the Ninject 2 relase!

Long version incoming:

The most elegant solution would be to overload the Rebind-behavior. I
tried that initially, but the problem is, the Rebind-method has no way
of knowing when the Binding is finished. A way would be to remember
the binding returned from the latest Rebind call and on the next
Rebind, Bind, Get (etc) call check if there is a remembered binding
from before and drop the old binding if necessary.

To clarify my design intend a bit further:

We have a netcf application which caters to a number of mostly
slightly different but similar use cases. Every use case consist of a
series of steps which are mostly executed in order, but the user also
can navigate between them. Because there really only are a handful of
base use cases, I decided to try something like "use case
inheritance", where I would design an abstract use case corresponding
to a Ninject module (not directly, but I abstracted it to a component
in my application to not be directly dependet on Ninject all parts but
the architecture layer of my program).

I then design the concrete use case by changing a few bindings a
adding the missing bindings. That way, if a customer does not want the
standard screen to display the data, I just assign him a freshly
inherited component where I would just change the binding for that
specific screen, like in this case:

Bind<INavigationForm>().To<SelectFromListPopup>().InScope(ctx =>
processScope).Named(NavigationConstants.SelectArticleState);

If the use case navigates into the SelectArticleState (wher the user
is to select a specific article from a number of available articles),
it would tell my IProzessController (the type which handles things
like WindowsForms caching, navigation logic and some other
administrative things):

Controller.ShowNavigationForm<ISelectFromListForm>(NavigationConstants.SelectArticleState,
PrepareFormDelegate);

The controller then tries to get an instance by calling

IServiceLocator.GetInstance<INavigationForm>(NavigationConstants.SelectArticleState),

casting it to the desired type, calling the PrepareFormDelegate (which
is a generic delegate and will match the type given) to enable some
actions from the application logic to e.g. load the available articles
to the form and will then Show() it (besides doing other things).


This design of use case inheritance is very helpful to us, because we
really only have like 3 base use case types, but something like 10
concrete use cases and for every use case there are about 5 different
customers, all with their own needs.

On 8 Apr., 17:36, Nate Kohari <nkoh...@gmail.com> wrote:
> The resolution order should match the order in which the bindings are
> registered. Maybe I'm missing something, but couldn't you just change the
> order of your bindings?
>
> -Nate
>
> On Thu, Apr 8, 2010 at 11:18 AM, Ian Davis <ida...@innovatian.com> wrote:
> > So, you would like to do something like,
>
> > Bind<T>().To<U>().InOrder(3);
> > Bind<T>().To<R>().InOrder(1);
> > Bind<T>().To<C>().InOrder(2);
>
> > Am I understanding correctly? If not syntactically, then conceptually?
>
> > -Ian
>
> > On Tue, Apr 6, 2010 at 11:30 PM, TWischmeier <
> > tim.wischme...@googlemail.com> wrote:
>
> >> It seems Google did not append my message to the corresponding
> >> discussion properly, I was responding to this thread:
>

> >>http://groups.google.com/group/ninject-dev/browse_thread/thread/52893...

> >> <ninject-dev%2Bunsu...@googlegroups.com<ninject-dev%252Buns...@googlegroups.com>

Reply all
Reply to author
Forward
0 new messages