Reputation:
I am working on an automation platform that is using Google Protocol buffers, the C# implementation of the protocol service inherits from a generated base class.
Each service represents a portion of the page and the actions that can be taken on that page, with this there are going to be several services that represent similar actions, ie any section that is a tab based interface.
Within the implementation of one of the services I have some utility code that handles navigating between the tabs, and waiting for the tab to be loaded.
What I would like to do is add an interface (possibly an empty interface) to the implementation and for any class that inherits that interface have the utility code accessible.
Some code to illustrate the configuration of what I'm looking for, the code is not an exact implementation only a super simplified version to get the point across:
public class TabWindowServiceImpl : AbstractTabWindowService, ITabNavigation
{
public ActionResult NavigateToTab1()
{
return TryNavigateToTab("tab1");
}
public ActionResult NavigateToTab2()
{
return TryNavigateToTab("tab2");
}
}
public interface ITabNavigation
{}
// This is an example of a function I would like to add to the ITabNavigation Interface
public ActionResult TryNavigateToTab(string tabId, string tabLoadedElementId)
{
try
{
//Driver is a static singelton
Driver.FindElement(tabId).Click();
Driver.WaitUntilPresent(tabLoadedElementId);
}
catch (Exception ex)
{
return new FailureActionResult(ex.Message);
}
}
Just final note, the TryNavigateToTab method ideally should not be publicly available on the TabWindowServiceImpl, only privately.
Upvotes: 1
Views: 80
Reputation: 8243
If I understand correctly, you're trying to add utility methods to classes that implement a certain interface, but without exposing those methods to the normal users of the interface.
AFAIK, this is not possible, and in fact doesn't make all that much sense. What you really should be using is a static class with utility methods. Something like this:
public static class Utilities
{
public static ActionResult TryNavigateToTab(string tabId, string tabLoadedElementId)
{
try
{
//Driver is a static singelton
Driver.FindElement(tabId).Click();
Driver.WaitUntilPresent(tabLoadedElementId);
// TODO return something
}
catch (Exception ex)
{
return new FailureActionResult(ex.Message);
}
}
}
Which the classes that want to use the methods can then use them like so (no interface needed):
public ActionResult NavigateToTab1()
{
return Utilities.TryNavigateToTab("tab1");
}
However, if you really want to "add the magic methods", you can get something similar by making methods into extension methods, on a class within a hidden namespace:
namespace Something.Something.Helpers
{
public static class Utilities
{
public static ActionResult TryNavigateToTab(this ITabNavigation self,
string tabId,
string tabLoadedElementId)
{
try
{
//Driver is a static singelton
Driver.FindElement(tabId).Click();
Driver.WaitUntilPresent(tabLoadedElementId);
// TODO: return something
}
catch (Exception ex)
{
return new FailureActionResult(ex.Message);
}
}
}
}
Then in any code that uses the interface, be sure to include the namespace and use the method prefixed with this.
:
using Something.Something.Helpers;
...
public ActionResult NavigateToTab1()
{
return this.TryNavigateToTab("tab1");
}
Upvotes: 1
Reputation: 73442
I assume by internally you mean "within the assembly". Just introduce another interface with modifier internal
.
internal interface ITabNavigationInternal : ITabNavigation
{
ActionResult TryNavigateToTab(string tabId, string tabLoadedElementId);
}
Then you must implement it with "Explicit interface implementation", Doing so you can't access that method without the interface instance, so that won't be exposed publicly since interface itself internal
.
public class TabWindowServiceImpl : AbstractTabWindowService, ITabNavigation, ITabNavigationInternal
{
ActionResult ITabNavigationInternal.TryNavigateToTab(string tabId, string tabLoadedElementId)
{
//Your implementation here.
}
}
Usecase:
ITabNavigationInternal instance = new TabWindowServiceImpl();
var res =instance.TryNavigateToTab(tabId, tabLoadedElementId);
Note: This can be still accessed through Reflection
or Dynamic
, but can't access directly with instance of the class.
Sorry if this doesn't compile or doesn't help, I haven't tested.
Upvotes: 1