superstator
superstator

Reputation: 3228

Ninject constructor arguments for multiple bindings

I have a simple class I use for processing notifications.

public class ApplePushNotifier : IApplePushNotifier
{
    public ApplePushNotifier(
        ILog log, 
        IMessageRepository messageRepository, 
        IUserRepository userRepository, 
        CloudStorageAccount account, 
        string certPath)
    {
        // yadda
    }

    // yadda
}

And a simple Ninject binding, which includes the string argument to locate a local certificate file:

kernel.Bind<IApplePushNotifier>().To<ApplePushNotifier>()
            .WithConstructorArgument("certPath", 
                System.Web.Hosting.HostingEnvironment.MapPath("~/bin/apns_universal.p12"));

This is obviously pretty basic, and everything has worked great. Now, I've added a second interface to that class:

public class ApplePushNotifier : IApplePushNotifier, IMessageProcessor

I can add a second binding like this:

kernel.Bind<IMessageProcessor>().To<ApplePushNotifier>()
            .WithConstructorArgument("certPath",
                System.Web.Hosting.HostingEnvironment.MapPath("~/bin/apns_universal.p12"));

And that works too, but the duplicated constructor argument gives me hives. I tried adding an explicit self-binding like this:

        kernel.Bind<ApplePushNotifier>().To<ApplePushNotifier>()
            .WithConstructorArgument("certPath",
                System.Web.Hosting.HostingEnvironment.MapPath("~/bin/apns_universal.p12"));
        kernel.Bind<IApplePushNotifier>().To<ApplePushNotifier>();
        kernel.Bind<IMessageProcessor>().To<ApplePushNotifier>();

But no dice - I get the old "No matching bindings are available" error.

Is there a way specify a constructor argument like this without either promoting it to a bindable type of it's own, or repeating it for every interface that class implements?

Upvotes: 0

Views: 325

Answers (2)

BatteryBackupUnit
BatteryBackupUnit

Reputation: 13243

Just create only one binding for both service-interfaces:

kernel.Bind<IApplePushNotifier, IMessageProcessor>().To<ApplePushNotifier>()
    .WithConstructorArgument(
        "certPath", System.Web.Hosting.HostingEnvironment.MapPath("~/bin/apns_universal.p12"))

Upvotes: 0

TOBrien
TOBrien

Reputation: 86

Depending on the nature of the inner workings of ApplePushNotifier then binding to a constant may help and would prevent repeating yourself.

    kernel.Bind<ApplePushNotifier>().ToSelf()
        .WithConstructorArgument("certPath", System.Web.Hosting.HostingEnvironment.MapPath("~/bin/apns_universal.p12"));

    var applePushNotifier = Kernel.Get<ApplePushNotifier>();

    kernel.Bind<IApplePushNotifier>().ToConstant(applePushNotifier);
    kernel.Bind<IMessageProcessor>().ToConstant(applePushNotifier);

Hope it helps.

Upvotes: 0

Related Questions