如何正确地将结构映射依赖解析器与 ASP.NET MVC Web 项目解耦?
在使用 ASP.NET MVC 开发 Web 项目时,我遇到了耦合问题。 当我构建自定义控制器工厂(或依赖项解析器,如果使用 MVC 3)时,我需要这个工厂以某种方式知道从哪里获取依赖项。这是我的代码:
//from Global.asax.cs
DependencyResolver.SetResolver(new StructureMapControllerFactory());
class StructureMapControllerFactory: IDependencyResolver {
Container repositories;
public StructureMapControllerFactory()
{
repositories = new RepositoriesContainer();
}
//... rest of the implementation
}
class RepositoriesContainer: Container
{
public RepositoriesContainer()
{
For<IAccountRepository>().Use<SqlAccountRepository>();
//...
}
}
StructureMapControllerFactory
类负责将依赖项注入控制器。正如我所说,它需要知道在哪里可以找到这些依赖项(我的意思是具体的类,例如服务和存储库实现)。
我有一个名为 MySite.Data
的单独类库,其中包含所有实现细节。合约(例如 IAccountRepository
)位于库 MySite.Contracts
中。现在,如果我直接从 MVC 项目引用此 MySite.Data
库,我的站点及其数据检索的实现之间将存在依赖关系。问题是我怎样才能删除它?这种情况下的最佳做法是什么?
我确信它确实有很多解决方法,只是我还没有找到。
While developing web project using ASP.NET MVC, I came up against a coupling problem.
When I build custom controller factory (or dependency resolver if using MVC 3), I need this factory to know somehow where to get dependencies from. Here's my code:
//from Global.asax.cs
DependencyResolver.SetResolver(new StructureMapControllerFactory());
class StructureMapControllerFactory: IDependencyResolver {
Container repositories;
public StructureMapControllerFactory()
{
repositories = new RepositoriesContainer();
}
//... rest of the implementation
}
class RepositoriesContainer: Container
{
public RepositoriesContainer()
{
For<IAccountRepository>().Use<SqlAccountRepository>();
//...
}
}
StructureMapControllerFactory
class is responsible for injecting dependencies into a controller. As I said, it needs to know where to find these dependencies (I mean concrete classes, like services and repositories implementations).
I have a separate class library called MySite.Data
, where all the implementation details live. Contracts, like IAccountRepository
, live in library MySite.Contracts
. Now, if I reference this MySite.Data
library directly from MVC project, there will be a dependency between my site and implementation of its data retrieval. The question is how can I remove it? What are best practices in this situation?
I'm sure it does have a bunch of workarounds, just I haven't found any yet.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
嗯,据我所知,你不能完全这样做。您的 MVC 项目确实需要了解它将使用的具体类。
无论如何,您都必须在某处提供这些容器注册,并且您将获得对定义该类型的项目/程序集的依赖关系。很快,您必须从 MVC 项目引用 MySite.Data。就像这样:
您可以使用 StructureMap
Registry
对象让生活变得更简单,但您也需要在某处包含这些注册表。通常这些位于主项目或某些“StructureMap-adapter”项目中,但无论如何您都需要进行参考。我建议您:
IControllerFactory
(如果您仅将其用于Controllers
中的 DI)。Registry
对象来提供所需的每个 IoC 注册。DependencyResolver
,即不是StructureMapControllerFactory
而是 CommonServiceLocator 改为 StructureMap 适配器。当然,不要害怕在主项目中进行引用 - 它们与耦合无关。它不会降低可维护性。但错误的架构确实如此,所以要担心这一点,而不是简单的参考。
Well, as I see it, you can't do exactly that. Your MVC project really really needs to know about concrete classes it is going to use.
You will anyway have to provide those container registrations somewhere and you'll get the dependency on the project/assembly where that type is defined. Shortly, you have to reference MySite.Data from MVC project. Like that:
You can make life simpler with StructureMap
Registry
objects but you need to include those Registries somewhere as well. Typically those are in the main project or some "StructureMap-adapter" project but you'd need to make reference anyway.I'd advise that you:
IControllerFactory
if you only use it for DI into yourControllers
.Registry
objects to provide each and every IoC registration ever needed.DependencyResolver
, i.e. not aStructureMapControllerFactory
but a CommonServiceLocator with StructureMap adapter instead.And, of course, don't be afraid of making references inside the main project - they have nothing about coupling. It doesn't decrease maintainability. But the wrong architecture does, so be worried about that, not simple reference.