views:

301

answers:

2

Given my code below, is there a way that the first WebTestingApp constructor can call the second before returning the new instance? I want to set some readonly fields in the constructor and, short of copy/pasting, I can't see how I can.

I feel that the answer will have something to do with constructor chaining, but I can't figure out how to do it, since the second WebTestingApp constructor implicitly calls base() (which is important as external users of the class shouldn't have to provide IRemoteFile and IWebServiceGateway instances).

    internal WebTestingApp(Result result, BrowserApp browserApp, IRemoteFile remoteFile, IWebServiceGateway webServiceGateway) : base(remoteFile, webServiceGateway)
    {
        // TODO: Need to invoke WebTestingApp(Result result, BrowserApp browserApp)
    }

    public WebTestingApp(Result result, BrowserApp browserApp)
    {
        // Set readonly vars here
    }

Here's the base class TestingApp's constructors:

    protected TestingApp() : this(S3File.Instance, WebServiceGateway.Instance) { }

    internal TestingApp(IRemoteFile remoteFile, IWebServiceGateway webServiceGateway)
    {
        this.remoteFile = remoteFile;
        this.webServiceGateway = webServiceGateway;
    }

WebTestingApp is derived from TestingApp. S3File and WebServiceGateway are singletons.

+2  A: 

You could switch the logic round like this:

internal WebTestingApp(Result result, BrowserApp browserApp, IRemoteFile remoteFile, IWebServiceGateway webServiceGateway) : base(remoteFile, webServiceGateway)
{
    // Set readonly vars here
}

public WebTestingApp(Result result, BrowserApp browserApp) : this(result, browserApp, S3File.Instance, WebServiceGateway.Instance)
{
}

This isn't a perfect solution either, as it duplicates the calls to the singletons in both classes.

David M
I'm not sure that'd work? Wouldn't it try to call WebTestingApp(Result, BrowserApp) with IRemoteFile and IWebServiceGateway instances?
Matthew Brindley
I have misread your question. Apologies. Will edit my answer.
David M
Edited mine, then saw you'd come up with the same. Oh well, glad you're sorted...
David M
Sorry, thanks anyway! :-)
Matthew Brindley
Just to confirm, this is working perfectly, thanks again.
Matthew Brindley
A: 

Sorry, I think I might've found the answer, by switching them around and having the second constructor call the first with the default IRemoteFile and IWebServiceGateway instances I can chain them together and include all 4 constructors.

    internal WebTestingApp(Result result, BrowserApp browserApp, IRemoteFile remoteFile, IWebServiceGateway webServiceGateway) : base(remoteFile, webServiceGateway)
    {
        // Set readonly fields here
    }

    public WebTestingApp(Result result, BrowserApp browserApp) : this(result, browserApp, S3File.Instance, WebServiceGateway.Instance) {}
Matthew Brindley