【发布时间】:2016-01-05 10:42:22
【问题描述】:
在我的 Web API 中,我将 Autofac 链接为 IoC 容器,我这样做:
域级别
public class Autofac
{
protected ContainerBuilder Builder { get; set; }
public Autofac()
{
this.Builder = new ContainerBuilder();
}
public virtual IContainer Register()
{
// Register dependencies
SetUpRegistration(this.Builder);
// Build registration.
var container = this.Builder.Build();
// End
return container;
}
private static void SetUpRegistration(ContainerBuilder builder)
{
// === DATALAYER === //
// MyRepository
builder.RegisterType<MyRepository>()
.As<IMyRepository>()
.InstancePerLifetimeScope();
// === DOMAIN === //
// MyManager
builder.RegisterType<MyManager>()
.As<IMyManager>()
.InstancePerLifetimeScope();
}
}
网络 API
public class Autofac : Domain.IoC.Autofac
{
public IContainer Register(HttpConfiguration config)
{
// Register your Web API controllers.
base.Builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
// OPTIONAL: Register the Autofac filter provider.
base.Builder.RegisterWebApiFilterProvider(GlobalConfiguration.Configuration);
// Complete registration and get container instance.
var container = base.Register();
// Set the dependency resolver to be Autofac.
config.DependencyResolver = new AutofacWebApiDependencyResolver(container);
// Done.
return container;
}
}
如您所见,它继承自 Domain 的基类并设置 Web API 特定配置。
用法
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
GlobalConfiguration.Configure(WebApiConfig.Register);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
new IoC.Autofac().Register(GlobalConfiguration.Configuration);
}
如您所知,它位于 global.asax。
问题
这适用于 Web API,但我不知道我需要做什么才能在 UnitTest 项目上下文中注册所有这些。
我的想法是,我将在 Web API 级别创建与 Autofac 类类似的实现,但不是使用模拟(完全忽略来自 Domain 的基类)。
任何指针?
【问题讨论】:
-
就我个人而言,我从来没有看到有必要(也不知道为什么它甚至可行)在单元测试中设置我的 IoC 容器。单元测试应该用于测试一段逻辑代码,该代码可以快速轻松地自行测试,而无需预先设置应用程序的其余部分。我认为您以错误的方式看待问题,应该单独测试每个部分而不是整体测试。
-
@StephenRoss:在理论上同意,但我需要测试依赖于
IRepositories的域管理器将访问数据库。我需要嘲笑那些,所以我实际上并没有全部删除......我认为这很难避免。 -
在这种情况下,您应该只设置域管理器所需的依赖项(在使用模拟的单元测试中,正如您已经说过的)。请记住,您不是在测试域管理器是否与您的所有
IRepositories一起工作,而是在测试数据流是否会以IRepository结束。然后对您的每个IRepositories进行单独的测试,以确保它们按照应有的方式进行。我当然希望您的域管理员不依赖应用程序的其余部分。 -
因为您已经使用界面分离了不同的存储库,这将使您可以轻松地测试您的域管理器。如果存储库本身继承自
DBContext,那就有点困难了,另一方面,如果你将DBContext作为类的依赖项,我通常将它包装在一个接口类中,这样你就可以简单地传递接口和类将简单地提供一个薄包装器,易于测试且相对简单。
标签: c# unit-testing dependency-injection inversion-of-control autofac