0

I would like to be able to register 2 class for the same interface in my Unity container. Then, I would like to select the current implementation based on a parameter.

Here is my interface:

public interface ICheckService
{
    HttpResponseMessage Validate(string p1, string p2);
}
}

My services:

public class CheckService1 : ICheckService
{
    public HttpResponseMessage Validate(string p1, string p2)
    {
      /////code
    }
}

public class CheckService2 : ICheckService
{
    public HttpResponseMessage Validate(string p1, string p2)
    {
        ////code
    }
}

In the bootstraper.cs I declare my services:

        `container.RegisterType<ICheckService, CheckService1>();`
        `container.RegisterType<ICheckService, CheckService2>();`

My API controller:

public class ServiceController : ApiController
{
    private readonly ICheckService _checkService;

    public ServiceController(ICheckService checkService)
    {
        _checkService = checkService;
    }
    [HttpGet]
    public HttpResponseMessage Validate(string p1, string p2)
    {
        return _checkService.Validate(p1, p2);
    }
 }

Now, I would like, when I cal my api, to select the implementation based on the p1 paramerter.

If p1 equals Service1 then the Validate method is called from Service1 class, and if p1 equals Service2, the validate method is called from Service2 class.

Thanks for your help.

3 Answers 3

1

You should use a factory and not the container for that. The factory implementation could request the proper implementation from the container internally (i.e. that's just an implementation detail and not nothing that the factory invoker should be aware of).

But the point is that using the IoC directly is not a good fit in your case.

public class ServiceController : ApiController
{
    private readonly ICheckServiceFactory _checkFactory;

    public ServiceController(ICheckServiceFactory factory)
    {
        _checkFactory = factory;
    }
    [HttpGet]
    public HttpResponseMessage Validate(string p1, string p2)
    {
        var service = _checkFactory.Create(p1);
        service.Validate(p1, p2);
    }
 }
Sign up to request clarification or add additional context in comments.

Comments

0

CheckService1 and CheckService2 in your case are implementation classes/details of the Validation. You can create a CheckServiceFactory that can create those classes for you during run-time. Register the factory class and not the implementation classes.

Comments

0

The other option is by using strategy pattern. A class will act as the factory of the check services. Factory class will initialize a dictionary of ICheckServices. The factory(ICheckServiceFactory) will be registered using the IoC container of choice:

public interface ICheckServiceFactory
{
    string Validate(string validationStrategy, string stringToValidate);
}

public class CheckServiceFactory : ICheckServiceFactory
{
    private readonly Dictionary<string, ICheckService> _checkServices;

    public CheckServiceFactory()
    {
        _checkServices = new Dictionary<string, ICheckService>
        {
            {"cash", new CheckService1()},
            {"card", new CheckService2()}
        };
    }

    public string Validate(string validationStrategy, string stringToValidate)
    {
        return  $"Parameter '{stringToValidate}' is Valid equal {_checkServices[validationStrategy].Validate(stringToValidate)} using {_checkServices[validationStrategy].CheckType}";
    }
}

Each check services implements the ICheckServices:

public interface ICheckService
{
    string CheckType { get; }

    bool Validate(string validateMe);
}

public class CheckService2 : ICheckService
{
    public string CheckType { get; }

    public CheckService2()
    {
        CheckType = "CheckService2";
    }

    public bool Validate(string validateMe)
    {
        return true;
    }
}

public class CheckService1 : ICheckService
{
    public string CheckType { get; }

    public CheckService1()
    {
        CheckType = "CheckService1";
    }

    public bool Validate(string validateMe)
    {
        return true;
    }
}

So your service controller will look similar to how you originally want it to look like:

public class ServiceController : ApiController
{
    private readonly ICheckServiceFactory _checkServiceFactory;

    public ServiceController(ICheckServiceFactory factory)
    {
        _checkServiceFactory = factory;
    }
    [HttpGet]
    public HttpResponseMessage Validate(string p1, string p2)
    {
        return _checkServiceFactory.Validate(p1, p2);
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.