Not able to Integrate AutoQuery in an existing service

Environment => ASP.NET Core Host
Inherit => ResourceService: Service and QueryResourceRequest: QueryDb

Hi, I’d like to integrate AutoQuery to an existing service. To do that I insert this in the service:

    public IAutoQueryDb AutoQuery { get; set; }

    public object Any(QueryResourcesRequest query)
    {
        var q = AutoQuery.CreateQuery(query, base.Request);
        return AutoQuery.Execute(query, q);
    }

but the CreateQuery return a null reference exception during the GetConnection internal method.

The Container have 2 differente IDbConnectionFactory registered on it but seems the AutoQuery.Db property continue to be null.

How Could I resolve this issue?

Please post the full StackTrace

Here you are:

at ServiceStack.ServiceStackHost.GetDbConnection(IRequest req) in C:\TeamCity\buildAgent\work\a61371dd01fad6bd\src\ServiceStack\ServiceStackHost.Runtime.cs:line 695
at ServiceStack.AutoQuery.GetDb[From](IRequest req) in C:\TeamCity\buildAgent\work\a61371dd01fad6bd\src\ServiceStack.Server\AutoQueryFeature.cs:line 551
at ServiceStack.AutoQuery.CreateQuery[From](IQueryDb1 dto, Dictionary2 dynamicParams, IRequest req) in C:\TeamCity\buildAgent\work\a61371dd01fad6bd\src\ServiceStack.Server\AutoQueryFeature.cs:line 561
at Msa.Core.Services.Globalization.ResourcesService.Any(QueryResourcesRequest query) in C:\code\af\tfvc\adam-factory\Development\Products\Msa\Core\Bare-Bones\Msa.Core.Services\Globalization\ResourcesService.cs:line 142
at ServiceStack.Host.ServiceRunner`1.Execute(IRequest request, Object instance, TRequest requestDto) in C:\TeamCity\buildAgent\work\a61371dd01fad6bd\src\ServiceStack\Host\ServiceRunner.cs:line 107

Thanks for your support.

It’s indicating the NRE is happening in ServiceStackHost.GetDbConnection(), do you have the OrmLiteConnectionFactory registered in the IOC?

Yes, I have multiple OrmLiteConnectionFactory registered on the container. Let me explain our projects architecture:

A bootstrapper, called during the app host configuration process, is responsible to register in the IOC container the available connections. During the configuration also our plugins, that contained our services, are registered.

When a service is instantiated, in the constructor the related engine will be resolved.
When an engine is instantiated, in the constructor the related repository and unitofwork will be resolved.

Any way, before integrate AutoQuery to our decoupled system, we’d like to test it inside an existing service. The service receive a container and inside the container the IDBConnectionFactory could be resolved by unit name to retrieve one of the available OrmLiteConnectionFactory available.

It doesn’t sound like your setup includes having registered an IDbConnectionFactory in the IOC so that HostContext.TryResolve<IDbConnectionFactory>() returns the instance to use in which case you’ll need to override GetDbConnection() in your AppHost to return the open IDbConnection you want ServiceStack to use.

Note this isn’t specific to AutoQuery, it’s required for all ServiceStack providers that require access to the DB.

During the AppHost configuration process I do this:

        ////Get environment configuration
        var coreConfiguration = container.Resolve<CoreConfiguration>();

        ////Initialize DBFactories
        var providerName = coreConfiguration.OrmLite.Provider;
        Type providerType = providerName.RetrieveType(coreConfiguration.OrmLite.Dialect);
        IOrmLiteDialectProvider provider = providerType.GetProperty("Provider").GetValue(null) as IOrmLiteDialectProvider;

        foreach (var connection in coreConfiguration.ConnectionStrings)
        {
            var dbFactory = new OrmLiteConnectionFactory(connection.value, provider);
            container.Register<IDbConnectionFactory>(connection.Name, dbFactory);
        }

In the service class I’ve tried to get the factory in two way:

HostContext.TryResolve(); => this return null

and

HostContext.Container.TryResolveNamed(“CoreConnection”) => this return an instance

So if I have understood correctly I’ve to override the GetDbConnection to retrieve the “Default” connection… Is it correct?

The GetDbConnection() implementation needs to return an open IDbConnection that you want ServiceStack to use for that request, it doesn’t matter how it’s resolved.

I’m not clear on why you’re using a custom factory but have you considered using the built-in named connections instead?

To be honest just because I don’t know that I could use different way to register multiple connection (my fault). I’m working on a porting from a old .NET project to a new .NET core architecture.

So using a NamedConnection I could avoid to override the GetDbConnection and let the built-in magic to change connection for me… is it right? Obviously by using attribute do decorate dto…

P.S.
Overriding the GetDbConnection it work fine but I don’t like it because we lost the de-couplig constraint of our project.

Yeah the [Multitenancy docs][1] shows a number of different options to specify which DB connection you want to use, e.g:

[ConnectionInfo(NamedConnection = "CoreConnection")]
public class QueryResourcesRequest { }

Overriding the GetDbConnection it work fine but I don’t like it because we lost the de-couplig constraint of our project.

You can use the same Attribute approach we have built into ServiceStack for decoupling and have your custom GetDbConnection() to look at that, but otherwise I don’t see how ServiceStack is supposed to know what DB connection it should be using?

Another option may be to force the connection in the AutoQuery dependency with a custom AutoQuery impl, e.g:

public IAutoQueryDb AutoQuery { get; set; }

public object Any(QueryResourcesRequest query)
{
    ((AutoQuery)AutoQuery).Db = ...; // DB connection to use
    var q = AutoQuery.CreateQuery(query, base.Request);
    return AutoQuery.Execute(query, q);
}
```

But this would require creating a custom impl for every AutoQuery service which reduces the value of AutoQuery where it creates all the implementations for you.


  [1]: http://%20http://docs.servicestack.net/multitenancy

Great explanation and great support. Now I’m on the right way to speed up the AutoQuery integration in my system.

Thanks a lot

1 Like