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.
CodePudding user response:
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
CodePudding user response:
Now, perhaps i'm missing something, but wouldn't something like
IModule module = (IModule)Activator.CreateInstance(typeof(DemoModule));
((DemoModule)module).ApiClient.DoStuff()
do what you're looking for?
Because it seems that you don't have to pull up the member to IModule expecially if DoStuff() is something specific to Demomodule (I assume other IModule won't have that)
CodePudding user response:
Add IAPIClient property to IModule:
public interface IModule<T> where T : IAPIClient
{
//Properties
string StoreName { get; }
T ApiClient { get; }
}
And DoStuff to IAPIClient:
public interface IAPIClient
{
IProxyManager ProxyManager { get; }
IHttpClient HttpClient { get; }
void DoStuff();
}
And you can do this:
IModule module = (IModule)Activator.CreateInstance(typeof(DemoModule));
module.ApiClient.DoStuff();
