I'm using a helpful RestClient, which handles Rest-calls to other Webservices. This RestClient is part of bigger Service-Clients which handle different Webservices by providing convenience-methods which are used by the businesslogic etc.. I'm using UnityContainers for dependency-injection.
I've got some sort of RestClient:
public interface IRestClient
{
T PostSomething<T>();
}
public class RestClient : IRestClient
{
public RestClient(string baseUrl) { }
public T PostSomething<T>() { /* post something */ }
}
Which i use in multiple ServiceClients:
public interface IServiceClient1
{
void Work1();
}
public class ServiceClient1 : IServiceClient1
{
private RestClient client;
private string myRestUrl = "ServiceUrl1";
public ServiceClient1(IRestClient client)
{
this.client = client;
client.SetUrl(myRestUrl); // i don't want to do this here. This should be done by unity when RestClient is instantiated
}
public void Work1()
{
/* do something */
client.PostSomething<string>();
}
}
public interface IServiceClient2
{
void Work2();
}
public class ServiceClient2 : IServiceClient2
{
private RestClient client;
private string myRestUrl = "ServiceUrl2";
public ServiceClient2(IRestClient client)
{
this.client = client;
client.SetUrl(myRestUrl); // i don't want to do this here. This should be done by unity when RestClient is instantiated
}
public void Work2()
{
/* do something */
client.PostSomething<string>();
}
}
Now I want to Inject those classes with UnityContainers:
container.RegisterType<IServiceClient1, ServiceClient1 >();
container.RegisterType<IServiceClient2, ServiceClient2 >();
// And here comes the problem:
container.RegisterType<IRestClient, RestClient>(new InjectionConstructor("ThisParameterShouldBeSetByServiceClient"));
Both ServiceClients
are much more different as shown in this example. This example may only show the problem.
I want to register the type RestClient
and I want that ServiceClientX
selects the string-parameter for the Constructor of RestClient
. And I don't want to set the Url in the Constructor of ServiceClient
.
How can I achieve this with UnityContainers
?
You have to use a factory for this. If the ServiceClient decides how to create a RestClient:
public class ServiceClient1 : IServiceClient1
{
private RestClient client;
private string myRestUrl = "ServiceUrl1";
public ServiceClient1(IRestClientFactory clientFactory)
{
this.client = clientFactory.CreateClient(myRestUrl);
}
public void Work1()
{
/* do something */
}
}
Unity injects the Factory and not the RestClient.
If the RestClient should be mocked the factory should be switched to a mock-factory.