【发布时间】:2012-04-18 14:47:26
【问题描述】:
假设您正在处理一个 ASP.NET MVC 项目,它在单个解决方案中将层拆分为不同的项目。每个项目都创建了 autofac 模块来连接依赖项。现在,我想扫描程序集并将所有模块注册到容器中。
我采用了类似于这里分享的扩展方法http://goo.gl/VJEct
public static void RegisterAssemblyModules(this ContainerBuilder builder, Assembly
assembly)
{
var scanningBuilder = new ContainerBuilder();
scanningBuilder.RegisterAssemblyTypes(assembly)
.Where(t => typeof(IModule).IsAssignableFrom(t))
.As<IModule>();
using (var scanningContainer = scanningBuilder.Build())
{
foreach (var m in scanningContainer.Resolve<IEnumerable<IModule>>())
builder.RegisterModule(module);
}
}
我的第一个问题是,考虑到这个示例是几年前提供的,这仍然是与当前版本的 autofac 一起使用的可行结构吗?
其次,MVC 应用程序依赖于其他层的功能,这意味着有时我需要使用 .InstancePerHttpRequest() 注册类型。但是,我还希望可以选择从非 Web 应用程序中引用它们,而不是依赖于 System.Web。注册可在这些不同上下文中使用的模块的最佳方法是什么?
【问题讨论】:
-
差不多一年前...但仍然很好奇。您是否设法很好地连接您的 MVC 应用程序模块而无需引用 mvc 并且您仍然可以在 http 请求的生命周期范围内正确使用它们?我现在的情况和你一样。选项有:web prj 中的所有模块注册或每个程序集中的模块注册...
-
到目前为止,我已经在必要时在每个程序集中采用了模块的方法。从这篇文章开始,autofac 在其核心 dll 中包含了一个 RegisterAssemblyModules 扩展方法。 code.google.com/p/autofac/wiki/Scanning#Module_Scanning。对于不引用任何 Web 组件的项目,对于大多数一般情况,我一直很好地将组件注册为 InstancePerDependency()。我尽量避免在主项目中进行大量注册。我发现你会放弃这种方式的一点灵活性,甚至可以放弃“更混乱”的注册设置。
-
好的。好资料。问题是(就我而言)当您注册实体框架 DBContexts(我使用几个有界上下文进行 DDD)并希望将它们注入存储库时,您希望它们具有作为 webrequest 的生命周期范围。这导致我参考 AutoFac(没关系)、AutoFac MVC 集成(嗯.. 可能没问题)和 MVC Web prj(不好)。我们项目中的其他组件我实际上没有指定生命周期范围,所以它们是 PerDependency。我实际上发现我可以用 InstancePerMatchingLifetimeScope("AutofacWebRequest") 连接我的 DBContext。我知道这是一个丑陋的参考。
-
... 继续:但对我来说,在其他项目的任何地方都不能引用 Web 项目。所以我会尝试这个解决方案,您可能会编写自己的扩展方法来调用 InstancePerMatchingLifetimeScope("AutofacWebRequest") ,这样您就可以确定“父”生命周期名称是正确的。问题是当您想使用相同的 autofac 模块来注册在非 WebContext 中使用的 DBContexts 时......例如后台批处理。然后你可能需要使用 MultiTenant(还没有看过)或者只是有其他模块用于批处理。
标签: asp.net-mvc architecture dependency-injection autofac