jeudi 10 décembre 2015

How to bridge between singleton and transient dependencies

I have a service that stores the applications state. For this reason I've made it singleton. It's passed into the constructor of some WebAPI controllers to expose some of it's state and functions. A permanent reference is held by a background worker which is continuously doing things and making state changes. This state service has some persistence in that certain changes result in db writes. These are non blocking but that's besides the point. The single service needs to reference one or more repositories. A repository is just a generic class that has a get and insert method for it's given type. It's passed an IDbConnection into it's constructor. The repositories themselfs are passed into the singleton service constructor.

DI does the build up of the chain and it throws an error due to singleton objects (the service) depending on transient objects (the repositories). I wasn't obvious to me at first but this does make sense and could cause concurrency issues.

http://ift.tt/1Nkfqp4

The DI suggestions are make the dependancies singleton, make the owner not singleton or pass in a factory for the depentancies instead. Therein lies my quandary.

We're talking about the interface between singleton and non-singleton and how that is bridged. The service needs to be singleton of the far left of the graph, and the IDbConnecton must be transient on the far right, so a factory is needed to be the bridge but where to put it.

I could inject a factory that creates repositories but that would mean creating a new repository object for each individual repository operation. This seems quite a wasteful thing to do. Admittedly the repository doesn't hold any state, but it does seems logical then to make the repository itself singleton and give it a factory that produces IDbConnections.

The factory could in fact just wrap a connection pool but that's implimentation detail. It feels somehow dirty making a repository singleton to satisfy the dependency chain, even though it does make logic sense when I think it through. Id appriciate it if anyone could sanity check me. It feels like there is some kind of mistake in my reasoning, or that I'm nibbling around the edges of a pattern that I don't know about.

Aucun commentaire:

Enregistrer un commentaire