0

This is a follow on question from How to register multiple IDbConnectionFactory instances using Funq in ServiceStack.net

I need to do the same (have one service access different db connections) - but the answers on the above-mentioned stackoverflow discussion don't completely make sense to me (and SO wouldn't let me add comments).

Does it mean, that you cannot use an implementation of a dependancy class eg IDbConnectionFactory (OrmLiteConnectionFactory) more than once per service? So if you need to use more than one, you need to create new implementations of it (for no other reason than to get a unique class name)?

I had hoped that, that was what the name parameter (in the container.Register method) was for (for identifying additional instances of the same class). Eg It would be handy if you could have something like this: container.Register("Db_1", c => new OrmLiteConnectionFactory(connString1, SqlServerOrmLiteDialectProvider.Instance)); container.Register("Db_2", c => new OrmLiteConnectionFactory(connString2, SqlServerOrmLiteDialectProvider.Instance)); Then to use each connection within your service like this: Db["DB_1"].Select... Db["DB_2"].Select or Db_1.Select.. Db_2.Select...

Call me lazy, but writing a class for no other purpose than to get a new type name (because it's 100% inheriting with no additional properties/methods) seems redundant.

I'm assuming I'm missing some crucial point of IoC/DI so would appreciate someone setting me straight.

Thanks Tim

Community
  • 1
  • 1
The Huff
  • 365
  • 1
  • 5
  • 15

1 Answers1

2

I believe that named instances in this case are used for the Service Locator pattern, which is seen as an anti-pattern by many.

For example, you could use named instances like this:

container.Register<IDbConnectionFactory>("Db_1", c => new OrmLiteConnectionFactory(connString1, SqlServerOrmLiteDialectProvider.Instance));
container.Register<IDbConnectionFactory>("Db_2", c => new OrmLiteConnectionFactory(connString1, SqlServerOrmLiteDialectProvider.Instance));

Then you could (but shouldn't) do something like this:

public void GetData() 
{
    var factory1 = container.TryResolveNamed<IDbConnectionFactory>("Db_1");
    var factory2 = container.TryResolveNamed<IDbConnectionFactory>("Db_2");

    ...
}

Mark Seemann has written a nice article about why you shouldn't use the Service Locator pattern.

With named instances, I don't see any way to avoid having the consumer require some knowledge about what's being injected.

Jeff Mitchell
  • 1,459
  • 1
  • 17
  • 33
  • Thanks Jeff. I see your point. I've added the additional interfaces, classes for IDbConnectionFactory's, created a new service class and updated the container that registers things. Now nothing works. How does registering an IDbConnectionFactory get turned into an IDbConnection (Db property on the Service class?) Must be something in SS. Not convinced if/when it closes the connections (dodgy). – The Huff Oct 13 '13 at 19:41
  • In more recent iterations of Service Stack, the Service class will now automatically look for an IDbConnectionFactory and in your container and create a connection for you. See the following; https://github.com/ServiceStack/ServiceStack/blob/4dabe00889989ddba6e64ab8e3f2da234a52a761/src/ServiceStack/Service.cs#L74 In your case, you've changed the names of the interface, so you'll lose the syntactic sugar. You'll need to handle opening of the connections your self in whatever mechanism you deem as most reasonable. – Jeff Mitchell Oct 16 '13 at 15:13