Reputation: 19903
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"));
Upvotes: 1
Views: 462
Reputation: 172646
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:
Upvotes: 1