cslaforum icon indicating copy to clipboard operation
cslaforum copied to clipboard

DI ConnectionManager ado.net

Open JacoJordaan opened this issue 5 years ago • 6 comments

Question I would you go about to do dependency injection with ado.net? I am still using the ConnectionManager like this: using (var ctx = ConnectionManager<SqlConnection>.GetManager(DbConnectionStrings.ConnectionStrings["QSDb"].ToString(), false, "QSDb"))

I know the ConnectionManager makes sure that the connections are re-used and was just wondering how to do DI with the same functionality in place?

Version and Platform CSLA version: 5.1.000 OS: Windows, Linux Platform: WPF, ASP.NET Core

JacoJordaan avatar Feb 20 '20 10:02 JacoJordaan

That's something I just haven't had time to write about yet. Too little time in each day...

Basically, your data portal operation methods (fetch, create, etc.) accept a ConnectionManager<T> as an injected parameter.

  [Fetch]
  private void Fetch(int id, [Inject] ConnectionManager<SqlConnection> ctx)

Then in the ConfigureServices method of the `Startup' class you need to add a transient service of that type. Something like this:

  services.AddTransient<ConnectionManager<SqlConnection>, () =>
      ConnectionManager<SqlConnection>.GetManager(......));

rockfordlhotka avatar Feb 21 '20 01:02 rockfordlhotka

@rockfordlhotka , thanks, that works perfectly.

How would you go about if you have multiple connection strings in your application, where some business object connects to another database?

At the moment it will always resolve to the one connection manager.

JacoJordaan avatar Feb 21 '20 11:02 JacoJordaan

I am not entirely sure @JacoJordaan ...

DI works based on types, not parameter values. So I suspect you'll need to create subclasses of ConnectionManager for each database?

rockfordlhotka avatar Feb 21 '20 23:02 rockfordlhotka

@rockfordlhotka , I also thought to create a subclass for each database, but settled on having one subclass with a GetManager method taking a parameter. Since I already have a DbConnectionStrings class that retrieve the database connections from the configuration, this works well. Not sure if there may be behind the scenes issues with this approach?

My subclass:

public class QSConnectionManager : IQSConnectionManager
    {
        public ConnectionManager<SqlConnection> GetManager(string dbName)
        {
            return ConnectionManager<SqlConnection>.GetManager(DbConnectionStrings.ConnectionStrings[dbName].ToString(), false, dbName);
        }
    }

Calling code in Dal: using (var ctx = qsConnectionManager.GetManager("QSDb"))

JacoJordaan avatar Feb 22 '20 12:02 JacoJordaan

@JacoJordaan That's exactly how to do it. Inject IQSConnectionManager and pass it the connection information, and you'll get back the right manager.

Honestly, I'd stop using ConnectionManager. It's a static resource, and those are hard to write tests around. It's also a form of a service locator, and I consider that to be an anti-pattern.

JasonBock avatar Feb 24 '20 18:02 JasonBock

@JasonBock I would not mind replacing the ConnectionManager, but I am a bit lost how to do this with ado.net and still retain functionality it provides with handling of connections. Any help in this matter will be appreciated.

JacoJordaan avatar Feb 24 '20 18:02 JacoJordaan