JamTay317
JamTay317

Reputation: 1017

Inheritance Of Generics And fluent APIs

Hello I am using the builder pattern and am having a Bit of trouble I'm hoping that you can help me out.

First I have a TableBuilderand it can build basic Tables like:

public abstract class TableBuilder:QueryBuilder
{
    public TableBuilder(Query query)
    {/* do things here*/}

    public TableBuilder Add(string tableName)
    {
        //do things to create a table
        return this;
    }
}

And I may want some sub classes from this like:

public class SelectTableBuilder:TableBuilder
{
    public SelectTableBuilder ChageStuff(string tableName)
    {
        //do cool stuff here
        return this;
    }
}

And:

public class CrossTabTableBuilder:TableBuilder
{
    public CrossTabTableBuilder DoOtherCoolThings(string name)
    {
        // do work here
        return this;
    }
}

So Now I have a QueryBuilder that looks something like:

public abstract class QueryBuilder
{        

    public Query Query {get;}
    public abstract TableBuilder Tables { get; }
}

And a subclasses of this:

public class SelectQueryBuilder : QueryBuilder
{
    public override TableBuilder Tables=> new SelectTableBuilder(Query);
}

public class CrossTabQueryBuilder : QueryBuilder
{
    public override TableBuilder Tables => new CrossTabTableBuilder(Query);
}

okay, so now when i go to access the Tables.Add method I loose the API of the correct table builder. How can I use Generics to make this return the correct API?

Upvotes: 0

Views: 79

Answers (1)

juharr
juharr

Reputation: 32286

You can make the QueryBuilder generic like this.

public abstract class QueryBuilder<T> where T : TableBuilder
{ 
    public Query Query {get;}
    public abstract T Tables { get; }
}

Then the implementations would be

public class SelectQueryBuilder : QueryBuilder<SelectTableBuilder>
{
    public override SelectTableBuilder Tables=> new SelectTableBuilder(Query);
}

public class CrossTabQueryBuilder : QueryBuilder<CrossTabTableBuilder>
{
    public override CrossTabTableBuilder Tables => new CrossTabTableBuilder(Query);
}

I'm not sure how you'd change TableBuilder since it also inherits from QueryBuilder. Just from what you're showing I'm not sure it should inherit from QueryBuilder at all.

Upvotes: 2

Related Questions