0

This question comes from another to Simplify OrmLite with AutoQuery.

ServiceStack AutoQuery allows all my different Get(AKindOfType dto) to share the same code, like below: (I have many models, like Company, my two more questions attempt to simplify the code further)

// ====== Model.cs ========
[Route("/company/search")]
public class QueryableCompany : QueryBase<Company>
{
    public int? Id { get; set; }
    public string Company { get; set; }
    public int? CompanyNo { get; set; }
    public bool? Active { get; set; }
}
public class Company
{
    [AutoIncrement]
    public int id { get; set; }
    public string company { get; set; }
    public int companyNo { get; set; }
    public bool active { get; set; }
}
// ====== Service.cs ========
public IAutoQuery AutoQuery { get; set; }

public object Get(QueryableCompanies dto)
{
    var q = AutoQuery.CreateQuery(dto, Request.GetRequestParams());
    var r = AutoQuery.Execute(dto, q);
    return r.Results; 
}

// ====== Global.asax.cs ========
public override void Configure(Container container)
{
    //...
    Plugins.Add(new AutoQueryFeature { MaxLimit = 100 });
    //...
}

Then, I have two more questions based on the code above.

1) Since I have a lot of request DTOs, their code in Get(QueryableXXX dto) is all the same; How can I use a single generic Get() method to return all different types of DTO, like:

public object Get<T>(T dto) where T : IQuery
{
    var q = AutoQuery.CreateQuery(dto, Request.GetRequestParams());
    return AutoQuery.Execute(dto, q).Results;
}

2) In the Company example above, class QueryableCompany seems so similar to class Company, can AutoQuery provide some Attributes to class Company's members, and avoid to create another similar QueryableCompany?

Community
  • 1
  • 1

1 Answers1

3

a) Have your Services share a common base class

You can't have services call a generic method signature as an entry point. But your services can inherit a common Service base Class which your implementation can call instead, e.g:

public class CompanyServices : MyServiceBase
{
    public object Get(QueryCompany request)
    {
        return base.MyQuery(request);
    }
}

b) Override the default class for AutoQuery Services

Another option for genericizing your implementations if you want all AutoQuery Services to remain the same is to provide your own Custom AutoQueryServiceBase class which all your AutoQuery Services can use instead, e.g:

public abstract class MyAutoQueryServiceBase : AutoQueryServiceBase
{
    public override object Exec<From>(IQuery<From> dto)
    {
        var q = AutoQuery.CreateQuery(dto, Request.GetRequestParams());
        return AutoQuery.Execute(dto, q).Results;
    }

    public override object Exec<From, Into>(IQuery<From, Into> dto)
    {
        var q = AutoQuery.CreateQuery(dto, Request.GetRequestParams());
        return AutoQuery.Execute(dto, q).Results;
    }
}

You can then tell AutoQuery to use your base class instead for all AutoQuery services with:

Plugins.Add(new AutoQueryFeature { 
    AutoQueryServiceBaseType = typeof(MyAutoQueryServiceBase)
});

c) Dynamically generate your Service entry points

If you need more flexibility you can follow the same approach AutoQuery uses to generate your Services implementations and register them dynamically/


2) In the Company example above, class QueryableCompany seems so similar to class Company, can AutoQuery provide some Attributes to class Company's members, and avoid to create another similar QueryableCompany?

You can't use the same POCO for both your Request Query DTO and the POCO DataModel you're querying since it's a build error to reference the class your defining in your class definition, e.g:

public class Company : IQuery<Company> {}

You can use inheritance to save properties although I personally recommend against doing so for Request DTOs:

public class QueryCompany : Company, IQuery<Company> {}

As C# doesn't support multiple inheritance your company class would either need to define IQuery properties explicitly or inherit the QueryBase class, e.g:

public class Company : QueryBase { ... }
Community
  • 1
  • 1
mythz
  • 141,670
  • 29
  • 246
  • 390