Milo Milo - 1 year ago 67
C# Question

C# Decorator Class using Default Class Version of Method

How do you leave a method the same as the default implementation if trying to decorate a class?

For example I am trying to add a property to a IWebDriver interface of the WebDriver class.

i.e.

public class MyWebDriver : IWebDriver
{
private IWebDriver _driver;
internal string _currentTest { get; set; }

internal MyWebDriver(IWebDriver driver)
{
_driver = driver;
}
}


Visual Studio IntelliSense had me implement the class (or interface) with a bunch of '
throw new NotImplementedException();
as the method body for the default WebDriver class methods.

i.e.

public IWebElement FindElement(By by)
{
throw new NotImplementedException();
}


My question is if I don't want to adjust the behavior of these methods at all how do I implement that? Do I just leave it all as that line in the body or do I have to for example (if this is the case how would it be done for the FindElement method w/ a return type and parameter?):

public string CurrentWindowHandle
{
get
{
return _driver.CurrentWindowHandle;
}
}

public ReadOnlyCollection<string> WindowHandles
{
get
{
return _driver.WindowHandles;
}
}

public void Close()
{
_driver.Close();
}

public void Quit()
{
_driver.Quit();
}


I am just trying to add a string variable to the IWebDriver interface to keep track of which test is running.

EDIT: I found an alternative solution to my initial problem (which was proper logging of test results) that does not involve implementing any new functionality but rather placing try/catches in the correct places.

The solution to this question can be found in the marked answer as well as further below where @AlexanderWinter shows an example of an implementation including a way to retrieve data globally.

Thank you for all the help.

Answer Source

Instead of extending the class, use external means to save the data. Something you can use is System.Runtime.CompilerServices.ConditionalWeakTable<TKey, TValue>.

You could use it in the following way:

class TestState
{
    public string Name { get; set; }
}

//initialization of some private field
ConditionalWeakTable<IWebDriver, TestState> myTestsByDriver = new ConditionalWeakTable<IWebDriver, TestState>();

...

//usage:
myTestsByDriver.GetOrCreateValue().Name = "My_First_Test";
//etc.