1

I have an API controller, in the constructor an instance of EmployeeService is instantiated with Unity.

I'd like inject the value of myTest in the constructor of EmployeeService, that's means an instance of Repository<Employee> will be created and the content of _myString will "TestString"

If it's possible how set the container ?

Thanks,

[RoutePrefix("api/employee")]
public class EmployeeController : ApiController
{
    string myTest = "TestString";
    readonly IEmployeeService _employeeService;

    public EmployeeController(IEmployeeService employeeService)
    {
        _employeeService = employeeService;
    }
}

public class EmployeeService : ServiceBase, IEmployeeService
{
    private readonly IRepository<Employee> _repoEmployee;
    private readonly string _myString;

    public EmployeeService(IRepository<Employee> repoEmployee, string myString)
    {
        _repoEmployee = repoEmployee;
        _myString = myString
    }
}

container
 .RegisterType<IRepository<Employee>, Repository<Employee>>()
 .RegisterType<IEmployeeService, EmployeeService>());

My Solution :

.RegisterType<IEmployeeService, EmployeeService>(
    new InjectionConstructor(
            typeof(IRepository<Employee>), 
            "MySetting"));
4
  • Can you explain WHAT you are actually trying to accomplish here. What you are trying to do doesn't feel quite right. Why do you need that value in your EmployeeService and why does it need to be defined in that particular controller? And what do you do in case that service is injected in a different controller? And what does this myTest actually represents? Commented Mar 16, 2015 at 12:19
  • @Steven I just want the value "TestString" from the controller in the EmployeeService. The why is not important. Commented Mar 16, 2015 at 12:22
  • Hi Kris, my experience is that the why actually is crucial, because the answer to your question will completely depend on the why. Commented Mar 16, 2015 at 12:38
  • 1
    To use in the service class some parameters (keys) coming from the web.config. These parameters are read in the controller and send to the service class Commented Mar 16, 2015 at 12:42

1 Answer 1

1

To use in the service class some parameters (keys) coming from the web.config. These parameters are read in the controller and send to the service class

The controller should not be concerned with reading from the configuration file. In doing so, it violates the Single Responsibility Principle. This causes maintainability issues; issues that you are already experiencing, since your design causes you trouble with testing and configuring your DI library.

Since these are configuration values, they will not change during the lifetime of the application (changing the config file will cause the application to restart). Because of this, there is no reason for the controller to read them (over and over again). Instead, you can read them once during startup and inject them into the class that needs that configuration value.

In case there are multiple classes that need that configuration value, you changes are high that you are missing an abstraction. For instance, instead of injecting a connection string into many classes, consider creating an ConnectionFactory that hides the connection string from those classes and allows creating a SqlConnection on request.

But in your case, I imagine doing something like this:

TimeSpan timeOut = TimeSpan.FromSeconds(Int32.Parse(
    ConfigurationManager.AppSettings["timeOut"]));

container.RegisterType<IRepository<Employee>, Repository<Employee>>();
container.RegisterType<IEmployeeService, EmployeeService>());
container.Register<IEmployeeService>(new InjectionFactory(c =>
    new EmployeeService(
        c.Resolve<IRepository<Employee>>(),
        timeOut)));

Reading configuration values at start up has the following advantages:

  • It prevents your application code from depending on the configuration system itself. This makes your code more reusable, testable and maintainable.
  • It allows the application to fail fast at start up in case it is configured incorrectly.
  • It allows you to verify the correctness of your DI configuration in a test suite, without having to have the exact same configuration file in your unit test project.
Sign up to request clarification or add additional context in comments.

2 Comments

Not work in my case, I got an error "Parameter less constructor missing", but I added my solution.
@Kris-l: I'm sorry, you need to use Register instead of RegisterType.

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.