Home > other >  How can i explicitly implement an interface while having implemented that interface multiple times i
How can i explicitly implement an interface while having implemented that interface multiple times i

Time:03-29

In my Unity C# project I have these interfaces:

interface IGameService
{
 void Initialize(params object[] args);
}

interface IADManager : IGameService
{
 void Show();
}

interface IIAPManager : IGameService
{
 void Purchase();
}

And a class:

public class MonatizationManager : IAPManager, IADManager
{
 ... 
}

I have a list of IGameService classes, that I need to initialize (also i'm using Zenject). For example:

// this basicly means that _iapSettingsProvider and _adSettingsProvider will contain link to a class that implements IADManager and IIAPManager interfaces. In my case this is the same class for these two  interfaces - MonatizationManager 
[Inject] private readonly ISomeSettingsProvider1 _someSettingsProvider1; // example
...
[Inject] private readonly IADManager _iapSettingsProvider;
[Inject] private readonly IIAPManager _adSettingsProvider;
...
[Inject] private readonly ISomeSettingsProvider2 _someSettingsProvider2; // example

// here i initialize my classes (some are managers, some are just providing game settings etc)
// all initQueue's elements must implement IGameService interface
var initQueue = new GameTaskQueue();
initQueue.Add(new GameTaskInitService(_someSettingsProvider1)); // example
...
initQueue.Add(new GameTaskInitService(_iapSettingsProvider));
initQueue.Add(new GameTaskInitService(_adSettingsProvider));
...
initQueue.Add(new GameTaskInitService(_someSettingsProvider2)); // example

// here my queue is starting to initialize my IGameService classes (basically just calling Initialize() method for each element in the queue)
initQueue.Start();

Here comes the problem: I have same class (MonatizationManager) for IADManager and IIAPManager while i also need to Initialize these interfaces separately. So, how do MonatizationManager class would look like?

First, i tried:

// it did not work
public class MonatizationManager : IAPManager, IADManager
{
 IGameService.IADManager.Initialize(params object[] args) {...}
 IGameService.IIAPManager.Initialize(params object[] args) {...}
}

Then i tried (didn't work either):

interface IADManager : IGameService
{
 new void Initialize(params object[] args);
 void Show();
}

interface IIAPManager : IGameService
{
 new void Initialize(params object[] args);
 void Purchase();
}

public class MonatizationManager : IAPManager, IADManager
{
 void IIAPManager.Initialize(params object[] args)
 {
  ...
 }

 void IADManager.Initialize(params object[] args)
 {
  ...
 }
// compiler wants me to also write this method, but i think i don't need it
 public void Initialize(params object[] args)
 {
  ...
 }
}

Is it possible to somehow explicitly implement Initialize(params object[] args) method for these two interfaces (IIAPManager and IADManager) in my MonatizationManager class?

CodePudding user response:

Your design is a bit overcomplicated. There's only a single Intialize-method you should implement, not two. It would be pretty confusing for a client to use your class and having to need to call Initialize twice. However that single implementation can of course do whatever you want, for example call two private methods

Furthermore your manager-class already is an IADManager, so there's no reason to also have a member of that type and use that one by calling its members (unless you implement the decorator-pattern or similar).

So I'd suggest to use this instead:

interface IGameService
{
    void Initialize(params object[] args);
}    
interface IADManager : IGameService
{
    void Show();
}    
interface IIAPManager : IGameService
{
    void Purchase();
}

public class MonatizationManager : IAPManager, IADManager
{
    void Initialize(params object[] args) 
    {
        // code for initializing the one interface
        // code for initializing the other interface
    }
    void Show() { ... }
    void Purchase() { ... }
}

As an aside you usuially initialize specific classes, not an interface. Although every class has some initialize-method doesn't neccessarily mean such initialization should be available on the public interface. Having such a design would enable multiple calls to Initialize for instance, which is usually not intended. Instead you should provide a fully usable class within the constructor-code (unless there's some heavy magic happening, in which case you would implement some lazy-loading). Then your client-code does not need to know if or if not it already initialized the class, as it already gets a fully initialized one.

  • Related