Constructor Injection when 2 parameters are from the same type

94 views
Skip to first unread message

Alexander

unread,
Jul 5, 2008, 5:37:39 AM7/5/08
to ninject
Hi!

I've the following problem:

I have a constructor with this signature:
public Configuration(IConfigurationService remoteConfigurationService,
IConfigurationService localConfigurationService) { ... }

How can I get this to work?

I want to have my bindings similar to this ones:
Bind<IConfigurationService>().To<RemoteConfigurationService>()....
Bind<IConfigurationService>().To<LocalConfigurationService>()....

Best regards
Alexander

Nate Kohari

unread,
Jul 5, 2008, 8:28:28 AM7/5/08
to nin...@googlegroups.com
Alexander:

In order to do this, you'll have to add another hint to the parameters in order to guide Ninject. You can do this one of two ways: first, you can use the [Tag] attribute to mark the different dependencies:

public Configuration(
  [Tag("remote")] IConfigurationService remoteConfigurationService,
  [Tag("local")] IConfigurationService localConfigurationService)
{ ... }

Then your bindings would look like this:

Bind<IConfigurationService>().To<RemoteConfigurationService>().Only(When.Context.Target.Tag == "remote");
Bind<IConfigurationService>().To<LocalConfigurationService>().Only(When.Context.Target.Tag == "local");

However, relying on string-based identifiers can be error-prone, so I would suggest creating attributes instead:

public class RemoteAttribute : Attribute {}
public class LocalAttribute : Attribute {}

Then your constructor would look like this:

public Configuration(
  [Remote] IConfigurationService removeConfigurationService,
  [Local] IConfigurationService localConfigurationService)
{ ... }

And your bindings would look like this:

Bind<IConfigurationService>().To<RemoteConfigurationService>().WhereTargetHas<RemoteAttribute>();
Bind<IConfigurationService>().To<LocalConfigurationService>().WhereTargetHas<LocalAttribute>();

If you don't want to use attributes, you can make it work by getting more creative with your bindings:

Bind<IConfigurationService>().To<RemoteConfigurationService>().Only(When.Context.Target.Name == "remoteConfigurationService");
Bind<IConfigurationService>().To<LocalConfigurationService>().Only(When.Context.Target.Name == "localConfigurationService"):

These bindings will work with your constructor as-is, but bear in mind that if you want an instance of RemoteConfigurationService, you will always have to name the argument "remoteConfigurationService", and if you want an instance of LocalConfigurationService, the argument will have to be called "localConfigurationService".

If this isn't clear, just ask, and I'll do my best to explain it a little better. :)


Thanks,
Nate

Alexander

unread,
Jul 5, 2008, 9:11:04 AM7/5/08
to ninject
In the meantime I came up with the same solution (attribute based).
I come from the Unity Container, hence I'm a bit clumsy ;-).

-Alexander
Reply all
Reply to author
Forward
0 new messages