Reputation: 1958
I have done some searching around but have not been able to figure out how to bind LinqToSql data context's with specified connection strings into different repositories.
This binding is performed in global.ajax when routes are registered. I'm using a fairly standard repository pattern to decouple the LinqToSql infrastructure from my application so that I can change the technology infrastructure in the future (NHibernate, EntityFramework etc.). Additionally, make my code easily unit testable and mockable.
I have something like this.
string desktopConnectionString = ConfigurationManager.ConnectionStrings["Desktop"].ConnectionString;
string messagingConnectionString = ConfigurationManager.ConnectionStrings["MessageQueue"].ConnectionString;
string usersConnectionString = ConfigurationManager.ConnectionStrings["Users"].ConnectionString;
// Map linqToSql entity types to interfaces
TableMapper typeFinder = new TableMapper();
typeFinder.Define<EzsDashboard>().As<IDashboard>();
typeFinder.Define<EzsDashboardGadget>().As<IGadget>();
typeFinder.Define<EzsDashboardGadgetAssignment>().As<IGadgetAssignment>();
...
IDesktopRepository dr = new DesktopRepository(new LinqToSqlDataSource(new DataContext(desktopConnectionString), typeFinder)));
Bind<IDesktopRepository>().ToConstant(dr).InRequestScope();
IUserRepository ur = new UserRepository(new LinqToSqlDataSource(new DataContext(usersConnectionString), typeFinder)));
Bind<IUserRepository>().ToConstant(ur).InRequestScope();
IMessageRepository mr = new MessageRepository(new LinqToSqlDataSource(new DataContext(messagingConnectionString), typeFinder)));
Bind<IMessageRepository>().ToConstant(mr).InRequestScope();
Whilst this physically works. I find the data in my asp.net MVC app often comes back stale. For example, I'll add a gadget to the dashboard it displays and if I check the database, it was saved correctly into the database. I reload the page and the dashboard doesn't show anything. Clicking around the application will sometimes cause it to 'refresh' and the data that was saved shows up.
Another way this is visible is if I make a changed to my web.config and trigger an application re-load. When I hit the dashboard everything shows up exactly as it should.
Can somebody please provide some help with binding connection string->DataContext->LinqToSqlDataSource->DomainRepository
Upvotes: 1
Views: 907
Reputation: 17692
It looks to me like your repositories are outlasting the scope that you expect. Am I correct to assume that the code in your question is in a Ninject module or global application start up? If so, I would change each of your bindings to something like this:
Bind<IDesktopRepository>().ToMethod(context => new DesktopRepository(new LinqToSqlDataSource(new DataContext(desktopConnectionString), typeFinder)))).InRequestScope();
I believe that you're getting the same repository across requests, because you've bound it to a constant. I would want a new repository per request, which the above code will provide.
Upvotes: 1
Reputation: 61893
I typed this but, on reflection, I have no idea what you are asking... Can you clarify:
You need to surface stuff like this (assuming I've inferred correctly that you want to dynamically be able to change your application's storage mechanism on the fly - you've stated what you are doing, not why you are doing it) as application logic.
Trying to abuse a DI container to do this for you is bad news - it doesnt retain a tree of objects it give the old configuration to, etc. Your application needs to manage this.
Think of the case where you switch storage from A to B. What if something in your app is contacting A in the middle of your operation and is about to retry? You dont want the container (or anyone else) handing it a B instead.
That's not to say that there are no legitimate use cases for such things. It's just that they're definitely not a common case or something that DI containers are typically used to manage.
... Or I may be missing something - in which case, it'd be interesting to hear more about your scheme and how you are attempting to map things to scopes etc.
Upvotes: 0