I’m using Unity to resolve Mike Hadlow’s implementation of generic repositories (linq to sql flavor) targeting multiple databases. The container configuration that works:
container.RegisterType<IConnectionStringProvider, HistoryConnectionProvider>(new TransientLifetimeManager())
.RegisterType<IConnectionStringProvider, MetaConnectionProvider>("meta", new TransientLifetimeManager())
.RegisterType<IDataContextProvider, DataContextProvider>(new TransientLifetimeManager())
.RegisterType<IDataContextProvider, DataContextProvider>("meta", new TransientLifetimeManager(), new InjectionConstructor(new ResolvedParameter<IConnectionStringProvider>("meta")))
// this registration of Repository<> resolves the history database by default
.RegisterType(typeof(IRepository<>), typeof(Repository<>), new TransientLifetimeManager());
// anything not targeting this database has to be declared
.RegisterType<IRepository<SpecificType>, Repository<SpecificType>>(new TransientLifetimeManager(), new InjectionConstructor(new ResolvedParameter<DataContextProvider>("meta")));
This seems unnecessarily verbose. So I’m currently trying different approaches. Using individual interfaces for each database:
IConnectionStringProvider historyConnectionProvider = new ConnectionProvider(connections.HistoryConnectionString);
IConnectionStringProvider metaConnectionProvider = new ConnectionProvider(connections.MetaConnectionString);
container.RegisterType<IDataContextProvider, DataContextProvider>("history", new TransientLifetimeManager(), new InjectionConstructor(historyConnectionProvider))
.RegisterType<IDataContextProvider, DataContextProvider>("meta", new TransientLifetimeManager(), new InjectionConstructor(metaConnectionProvider))
.RegisterType(typeof(IHistoryRepository<>), typeof(Repository<>), new TransientLifetimeManager(), new InjectionConstructor(new ResolvedParameter<IDataContextProvider>("history")))
.RegisterType(typeof(IMetaRepository<>), typeof(Repository<>), new TransientLifetimeManager(), new InjectionConstructor(new ResolvedParameter<IDataContextProvider>("meta")));
Unfortunately, this doesn’t work. The result is the last type of IDataContextProvider registered getting injected into every type of Repository. Thanks in advance for any help.
Solution to the original question
Unity needed a unique type, as well as interface. I’m still unsure as to why constructor injection didn’t handle this. This works:
Unfortunately, this sets up a situation where consuming classes need knowledge of where their data is coming from, which I wasn’t happy with.
Better Design
I wanted to leave my dbmls generated (so this ruled out making my models adhere to a certain interface), so I just threw them in different sub folders, causing the designer to generate a different namespace for each database.
Then, in my Repository implementation, I did the following:
I think one step past this would be to build a custom type resolver for unity to check the namespace for me and return to injecting the data context (this will be necessary before unit of work can be implemented). I’m not going to mark this as the answer quite yet in case someone has a better solution.