AutoQuery to avoid repetitions

I spend a lot of time today creating what seems in essence to be the same code over sand over again:
I’ve got an Datamodel that uses XPO (devexpress), I can not change that.
I created DTO’s, Services etc. for each separate XPO class like this
Task - XPO class
TaskDTO - POCO for Servicestack
TaskByKey - request to find a task by using it’s PK. PK always named OID, always with route “/Task/{Id}”
TaskByKeyResponse - the response to the request, always returning a TaskDTO (OID = 0 signals not found)
TaskServices - where the code sits to retrieve etc. the XPO record(s) and transfer (Convert) them to the DTO

The code for the service is below, my question is whether or not I can/should use AutoQuery (and how) to generate a generic solution to get this functionality?

    public class TaakServices: Service
{
    public object Any(TaakByKey request)
    {
        var taak = XafGlobal.securedObjectSpace.GetObjectByKey<Taak>(request.Id);  
        if (taak != null)
        {
            var result = taak.ConvertTo<TaakDTO>();
            var back = new TaakByKeyResponse() { Result = result };
            back.Result.OID = request.Id;
            return back;
        }
        else
        {
            return new TaakByKeyResponse() { Result = new TaakDTO() { OID = 0 } };
        }
    }
}

Remarks: The ‘Any’ should probably be ‘Get’ and using Id in the route (instead of OID) is probably also not very consequent.

You shouldn’t think of the Request/Response DTO’s as duplicate code, they’re discrete types that defines the contract and provides a single source of Reference for your Services. DTO’s essentially use a class declaration as a DSL to design your API, it’s not something I’d try to hide behind inheritance, genericize or anything else that could affect their usability and discoverability on the client.

But otherwise the code within your Service implementation can be genericized using normal techniques you’d use to genericize any C# code. e.g. If your DTO’s implement a shared interface it will let you use common logic to populate that interface. Otherwise you could fallback to using reflection if you can predict the properties at a performance and readability cost.

AutoQuery is helpful if you’re using OrmLite since it provides rich querying functionality around a table with just a single Request DTO definition, but if you’re using a different ORM or Repository it wont be useful.

Although the techniques AutoQuery uses to dynamically generate Services can also be useful, but that’s an advanced customization technique using Reflection.Emit to dynamically generate the services implementation and dynamically register Services, but you should only attempt this if you’re comfortable meta programming with Refleciton.Emit.