如何使用 LinqToSQL 和存储库模式为 ASP.NET MVC 配置 Ninject

发布于 2024-09-10 07:33:42 字数 1745 浏览 2 评论 0原文

我已经进行了一些搜索,但无法弄清楚如何将 LinqToSql 数据上下文与指定的连接字符串绑定到不同的存储库中。

当注册路由时,此绑定在 global.ajax 中执行。我使用相当标准的存储库模式将 LinqToSql 基础架构与我的应用程序解耦,以便我可以在将来更改技术基础架构(NHibernate、EntityFramework 等)。此外,使我的代码可以轻松进行单元测试和模拟。

我有这样的东西。

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();

虽然这在物理上有效。我发现我的 ASP.NET MVC 应用程序中的数据经常会变得过时。例如,我将向它显示的仪表板添加一个小工具,如果我检查数据库,它会正确保存到数据库中。我重新加载页面,仪表板没有显示任何内容。单击应用程序有时会导致其“刷新”并显示保存的数据。

另一种可见的方式是,如果我对 web.config 进行更改并触发应用程序重新加载。当我点击仪表板时,一切都完全按照预期显示。

有人可以提供一些有关绑定连接字符串->DataContext->LinqToSqlDataSource->DomainRepository 的帮助吗

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

总以为 2024-09-17 07:33:42

在我看来,您的存储库超出了您预期的范围。我是否正确地假设您问题中的代码位于 Ninject 模块或全局应用程序启动中?如果是这样,我会将您的每个绑定更改为如下所示:

Bind<IDesktopRepository>().ToMethod(context => new DesktopRepository(new LinqToSqlDataSource(new DataContext(desktopConnectionString), typeFinder)))).InRequestScope();

我相信您在各个请求中都会获得相同的存储库,因为您已将其绑定到常量。我希望每个请求都有一个新的存储库,上面的代码将提供该存储库。

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.

两仪 2024-09-17 07:33:42

我输入了此内容,但经过反思,我不知道您在问什么...您能否澄清一下:

  • 在高层次上,这些连接字符串在您的应用程序中实现了什么,
  • 您认为您的系统出了什么问题?
  • 您认为这是 ASP.NET 问题还是 DI 问题?您是否在会话等中缓存内容?

您需要展示这样的内容(假设我已经正确推断出您希望能够动态地动态更改应用程序的存储机制 - 您已经说明了您正在做什么,而不是为什么 你正在做这件事)作为应用程序逻辑。

尝试滥用 DI 容器来为你做这件事是个坏消息 - 它不会保留它提供旧配置的对象树,等等。你的应用程序需要管理这个。

考虑一下您将存储从 A 切换到 B 的情况。如果您的应用程序中的某些内容在操作过程中正在联系 A 并准备重试,该怎么办?你不希望容器(或其他任何人)给它一个 B。

这并不是说这些东西没有合法的用例。只是它们绝对不是常见情况,也不是 DI 容器通常用来管理的情况。

...或者我可能会遗漏一些东西 - 在这种情况下,了解更多有关您的方案以及您如何尝试将事物映射到范围等的信息会很有趣。

I typed this but, on reflection, I have no idea what you are asking... Can you clarify:

  • at a high level, what do these connection strings achieve in your app
  • what you feel is going wrong in your system?
  • do you feel this is an ASP.NET issue or a DI issue? Are you cahcing stuff in a session etc.?

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文