【发布时间】:2017-12-04 23:12:41
【问题描述】:
我正在尝试学习如何使用依赖注入,但是在涉及到我的数据库时遇到了一些麻烦。到目前为止,这是我的过程:
我有一个 MVC 项目,其中控制器使用我的类库中的不同存储库。 所有存储库都使用相同的数据库。
一开始我使用SimpleInjector注册Repositories Application_start方法:
var container = new Container();
container.Options.DefaultScopedLifestyle = new WebRequestLifestyle();
var client = new GraphClient(uri, username, password);
container.Register<IRepoA>(() => new RepoA(client);
container.Register<IRepoB>(() => new RepoB(client);
container.RegisterMvcControllers(Assembly.GetExecutingAssembly());
container.Verify();
DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(container));
在每种方法中,我都这样做了:
client.Connect();
client.performSomeQuery();
client.Dispose();
这可行,但这意味着我每次调用方法时都会重新连接到数据库。 为避免这种情况,将连接调用移至此处:
var container = new Container();
container.Options.DefaultScopedLifestyle = new WebRequestLifestyle();
var client = new GraphClient(uri, username, password);
client.Connect();
container.Register<IRepoA>(() => new RepoA(client);
container.Register<IRepoB>(() => new RepoB(client);
container.RegisterMvcControllers(Assembly.GetExecutingAssembly());
container.Verify();
但是我从来没有处理掉我的连接。
我现在想的是注册我的数据库客户端;
container.RegisterSingleton(() =>
{
var client = new GraphClient(uri, username, password);
client.Connect();
return client;
});
然后像这样注入它:
container.Register<IRepoA>(() => new RepoA(container.GetInstance<GraphClient>()));
这是正确的做法吗?
是否正确理解连接将在容器生命周期结束时被释放?
当我注册客户端时,我确实得到了一个“隐式捕获的闭包:容器”。
【问题讨论】:
-
为每个请求创建一个新连接将是正常的方法。想一想——一个 Web 应用程序可能必须同时处理数十或数百个请求。你不希望这些东西都在争夺同一个实际的连接对象。
-
我刚读过这篇文章,认为调用@GPW 很昂贵“对于每个要与之通信的数据库,您应该只拥有一个实例(通常是一个)这样可以避免过多的调用到需要往返 Neo4j 服务器的 Connect() 方法”link 在每个方法中调用 connect 是否足够(就像我首先做的那样)或者我应该在每个方法中使用 (var client = new GraphClient(_uri, _username, _password) ) { client.Connect();客户端.Query();客户端.Dispose(); }
-
我明白了,我没有意识到您使用的是线程安全的特定库并建议使用单例方法。您使用 Lambda 注册课程有什么原因吗?我希望您只需要使用 DI 注册类及其实现 - 它实际上应该为您创建它们(因此您无需指定如何创建 IRepoA 并因此避免关闭警告)
标签: c# model-view-controller dependency-injection database-connection simple-injector