Pull up Generic Type to interface
I have an IModule
interface defined as below:
public interface IModule
{
//Properties
string StoreName { get; set; }
void Execute();
T ApiClient; // <-- How do I do this?
}
I also have an abstract class defined as:
public abstract class ModuleBase<T> : IModule where T : IAPIClient
{
public T ApiClient { get; private set; }
public abstract Task Execute();
}
I then inherit ModuleBase
in a class such as:
public class DemoModule : ModuleBase<DemoApiClient>
{
public override string StoreName => "Demo"
public override async Task Execute(){
ApiClient.DoStuff();
//... some long running stuff here
}
}
DemoApiClient
is defined as:
public class DemoApiClient : IAPIClient
{
public IProxyManger ProxyManager {get; set;}
public IHttpClient HttpClient {get; set;}
public void DoStuff() {
Console.Log("DemoApiClient - DoStuff");
}
}
IAPIClient
is an interface with the following declarations:
public interface IAPIClient
{
IProxyManager ProxyManager { get; }
IHTTPClient HttpClient { get; }
}
How can I pull up the generic ApiClient
on ModuleBase
up to IModule
? I want to ensure that every implementation of IModule
can implement the implementation of IAPIClient
?
The reason I need this is because of the following example:
IModule module = (IModule)Activator.CreateInstance(typeof(DemoModule));
module.ApiClient.DoStuff()
Note that DoStuff()
is specific to DemoApiClient
and other implementations of IAPIClient
will contain methods specific to them. For this reason, I cannot pull up DoStuff()
to IAPIClient
.
Solution 1:
You need to make IModule
generic
public interface IModule<T> where T : IApiClient
{
Task Execute();
T ApiClient {get;}
}
Then:
public abstract class ModuleBase<T> : IModule<T> where T : IAPIClient
{
public T ApiClient { get; private set; }
public abstract Task Execute();
}
You'll need to know the type:
DemoModule module = (DemoModule)Activator.CreateInstance(typeof(DemoModule));
module.ApiClient.DoStuff()
But lets take a step back here; why do you think IModule
needs to know about the APIClient at all, when you never use it outside of the base class?
You original code should work just fine as you only call ApiClient.DoStuff();
from Execute