Reputation: 95
In ASP.NET 5, I have an IRepository
interface that I used to access some databases, like this:
public interface IRepository {
IQueryable<T> QueryItems(string sql);
}
public class Repository : IRepository {
private readonly string ConnectionString;
public Repository(string connStr) {
// Save the injected connection string
this.ConnectionString = connStr;
}
public IQueryable<T> QueryItems(string sql) {
// Implementation ignored here
}
}
In my Startup.cs
class, I am registering the IoC/DI like this:
services.AddTransient<IRepository>(s => new Repository("DUMMY_CONNSTR"));
That all works fine if I only have one connection string. However, how can I register and subsequently inject the correct IRepository
if I use the Repository to connect to 2+ different databases with different connection strings?
services.AddTransient<IRepository>(s => new Repository("DUMMY_CONNSTR"));
services.AddTransient<IRepository>(s => new Repository("DIFFERENT_CONNSTR"));
In older IoC/DI systems, I would have use "named" implementations that could be resolved with something like a [Dependency("DUMMY")]
attribute on the constructor parameter.
Any help would be appreciated.
Upvotes: 2
Views: 2563
Reputation: 57783
You can substitute StructureMap or Autofac for the default DI container (see my blog post for detailed instructions). Both support "named" interface registration (StructureMap named instances and Autofac named and keyed services).
Additionally, if you target dnx451
, you can use Autofac's WithKey
attribute. Using the Visual Studio sample project from the blog post, add the following dependency in project.json:
"frameworks": {
"dnx451": {
"dependencies": {
"Autofac.Extras.AttributeMetadata": "4.0.0"
}
}
},
Given a test class with the following constructor:
public MyClass([WithKey("logging")] IRepository repository)
{
Repository = repository;
}
you would register everything in ConfigureServices
(note the use of WithAttributeFilter()
:
containerBuilder.Register(c => new Repository("DEFAULT_CONNSTR")).Keyed<IRepository>("default");
containerBuilder.Register(c => new Repository("LOGGING_CONNSTR")).Keyed<IRepository>("logging");
containerBuilder.RegisterType<MyClass>().WithAttributeFilter();
Upvotes: 0
Reputation: 1943
There are a few approach that you can take one is to inject a factory and base on the specific criteria you can produce a repository, the other approach is use a Dispatcher that also produce the repository base on the criteria, below is a question that I ask with the same problem. The question below have both approach but they were codding a beta version of .net core
See this question for reference and code
Upvotes: 1