1

I have a library that's meant to be used both on desktop apps and web apps.

This library has a reference to an external data-access component that on desktop should be bound as singleton and on web should be on request scope.

  • Desktop project references Core project
  • Web project references Core project
  • Core project references ExternalComponent

Today I'm forced to do this on the web-client:

Bind<ExternalComponent.IDataAccessComponent>()
     .To<ExternalComponent.DataAccessComponent()
     .InRequestScope()
     .WithConstructorArgument(...);

And on the desktop client, the same but with InSingletonScope() which forces my web and desktop apps to reference ExternalComponent.dll which is not my intention.

How can I make the binding so I can specify from the client (web or desktop) the scope that I need this external component to be on, without having the client to reference this data-access component?

I'm thinking some method on the Core project that receives the scope that the client needs and set all up, but i can't find something in the Ninject API that let's me do that.

David Lay
  • 2,956
  • 4
  • 27
  • 48
  • Why is that reference a problem? In the end you need to make sure that the ExternalComponent assembly is present in the base path for both applications because the core projects needs it. – Daniel Marbach Aug 16 '12 at 17:17
  • Because I want to avoid a unnecesary reference. ExternalComponent is only going to be used by Core and there is no use case for it to be referenced by clients, except the ninject binding configuration. – David Lay Aug 16 '12 at 18:22
  • The whole binding syntax is generic. The generic type T is defined with the Bind method. You could only achieve what you want if you use the System.Type accepting bind methods or if you use object binding. I'll dump an example as an answer. – Daniel Marbach Aug 16 '12 at 18:35

1 Answers1

1

I'm not sure why this is necessary but it is only possible when using the syntax that accepts System.Type:

public class CoreModule : NinjectModule
{
    public override void Load()
    {
        this.Extend(this.Bind(typeof(IDataAccessComponent)).To(typeof(DataAccessComponent))).WithConstructorArgument("foo", "bar");
    }

    protected virtual IBindingNamedWithOrOnSyntax<object> Extend(IBindingInSyntax<object> bindingWhenInNamedWithOrOnSyntax)
    {
        return bindingWhenInNamedWithOrOnSyntax;
    }
}

public class WebClientModule : CoreModule
{
    protected override IBindingNamedWithOrOnSyntax<object> Extend(IBindingInSyntax<object> bindingWhenInNamedWithOrOnSyntax)
    {
        return bindingWhenInNamedWithOrOnSyntax.InRequestScope();
    }
}

public class ClientModule : CoreModule
{
    protected override IBindingNamedWithOrOnSyntax<object> Extend(IBindingInSyntax<object> bindingWhenInNamedWithOrOnSyntax)
    {
        return bindingWhenInNamedWithOrOnSyntax.InSingletonScope();
    }
}

The above removes the strong binding semantics.

Ruben Bartelink
  • 59,778
  • 26
  • 187
  • 249
Daniel Marbach
  • 2,294
  • 12
  • 15