MKP
MKP

Reputation: 65

Passing non-instantiated classes and interfaces to generic methods

I have inherited hundreds of statements like this:

mockKernel.Setup(x => x.Bind<IAddressService>().To<AddressService>())
          .Returns(new BindingConfigurationBuilder<AddressService>(bindingConfiguration, "ServiceName", mockKernel.Object));

... as part of tests for hundreds of statements that resemble this:

_kernel.Bind<IAddressService>().To<AddressService>().InRequestScope();

I'd like to write something like this:

private void SetupBindAtoB<TInterface, TImplementation>(TInterface a, TImplementation b)
    where TImplementation : TInterface
{
  mockKernel.Setup(x => x.Bind<TInterface>().To<TImplementation>())
            .Returns(new BindingConfigurationBuilder<TImplementation>(bindingConfiguration, "ServiceName", mockKernel.Object));
}

... and then call it like this:

SetupBindAtoB(IAddressService, AddressService);

But I can't. I have to pass a real object to SetupBindAtoB, like this:

SetupBindAtoB((IAddressService) null, (AddressService) null);

Is it possible to avoid creating real objects to pass to SetupBindAtoB?

Upvotes: 2

Views: 50

Answers (2)

adjan
adjan

Reputation: 13684

You have two argument parameters that are unused (TInterface a and TImplementation b). Only the type parameters themselves (IInterface and IImplementation) are relevant. So just remove the unnecessary parameters:

private void SetupBindAtoB<TInterface, TImplementation>()
    where TImplementation : TInterface
{
  mockKernel.Setup(x => x.Bind<TInterface>().To<TImplementation>())
            .Returns(new BindingConfigurationBuilder<TImplementation>(bindingConfiguration, "ServiceName", mockKernel.Object));
}

Then you can call the method as follows:

SetupBindAtoB<IAddressService, AddressService>();

In your approach, you are basicially relying on the type inference from the types of the arguments that allows to omit to specify the type parameters themselves. Usually this type inference makes the method invocation shorter. In your case, this just makes it more complicated:

SetupBindAtoB((IAddressService) null, (AddressService) null);

is actually a "shorthand" for

SetupBindAtoB<IAddressService, AddressService>(null, null);

Upvotes: 1

TheGeneral
TheGeneral

Reputation: 81583

Have you tried this?

private void SetupBindAtoB<TInterface, TImplementation>()
    where TImplementation : TInterface
{
  mockKernel.Setup(x => x.Bind<TInterface>().To<TImplementation>())
            .Returns(new BindingConfigurationBuilder<TImplementation>(bindingConfiguration, "ServiceName", mockKernel.Object));
}

Usage

SetupBindAtoB<IAddressService,AddressService>();

Upvotes: 2

Related Questions