gpt4 book ai didi

c# - 从 MVC 的 DependencyResolver 过渡到 AutofacWebApiDependencyResolver - .Current 在哪里?

转载 作者:太空狗 更新时间:2023-10-30 01:04:41 28 4
gpt4 key购买 nike

我让 AutoFac 与 MVC4 一起正常工作。我正在尝试过渡到 Web API 2。这是我设置 AutoFac 的内容:

public class AutofacRegistrations
{
public static void RegisterAndSetResolver()
{
// Create the container builder.
var containerBuilder = new ContainerBuilder();

// Register the Web API controllers.
containerBuilder.RegisterApiControllers(Assembly.GetExecutingAssembly());

// Only generate one SessionFactory ever because it is expensive.
containerBuilder.Register(x => new NHibernateConfiguration().Configure().BuildSessionFactory()).SingleInstance();

// Everything else wants an instance of Session per HTTP request, so indicate that:
containerBuilder.Register(x => x.Resolve<ISessionFactory>().OpenSession()).InstancePerApiRequest();
containerBuilder.Register(x => LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType)).InstancePerApiRequest();

containerBuilder.RegisterType<NHibernateDaoFactory>().As<IDaoFactory>().InstancePerApiRequest();
containerBuilder.RegisterType<StreamusManagerFactory>().As<IManagerFactory>().InstancePerApiRequest();

// Build the container.
ILifetimeScope container = containerBuilder.Build();

// Create the depenedency resolver.
var dependencyResolver = new AutofacWebApiDependencyResolver(container);

// Configure Web API with the dependency resolver.
GlobalConfiguration.Configuration.DependencyResolver = dependencyResolver;
}
}

我非常确信所有这些都是正确的。当我尝试设置一些测试用例时,我的问题就出现了。我的测试用例的基类不是 Controller ,所以它不会自动传递任何东西。在 MVC4 中我做了以下事情:

[SetUp]
public void SetUp()
{
HttpSimulator = new HttpSimulator().SimulateRequest();

Logger = DependencyResolver.Current.GetService<ILog>();
DaoFactory = DependencyResolver.Current.GetService<IDaoFactory>();
Session = DependencyResolver.Current.GetService<ISession>();
ManagerFactory = DependencyResolver.Current.GetService<IManagerFactory>();
}

[TearDown]
public void TearDown()
{
HttpSimulator.Dispose();
}

不幸的是,没有 DependencyResolver.Current在 WebAPI 中。所以我想知道如何正确地做到这一点?

这可以构建,但不正确。我收到消息“ session 已关闭!”当我尝试执行测试用例时:

[SetUp]
public void SetUp()
{
using (var scope = GlobalConfiguration.Configuration.DependencyResolver.BeginScope())
{
// TODO: Consider initializing Helpers during setup to keep this DRY.
Logger = (ILog)scope.GetService(typeof(ILog));
DaoFactory = (IDaoFactory)scope.GetService(typeof(IDaoFactory));
Session = (ISession)scope.GetService(typeof(ISession));
ManagerFactory = (IManagerFactory)scope.GetService(typeof(IManagerFactory));
}
}

最佳答案

使用 WebAPI,您不需要访问当前解析器,因为当前依赖范围通常与入站 HttpRequestMessage 一起出现。该消息还负责生成新的请求范围。

您可以在 System.Net.Http.HttpRequestMessageExtensions.GetDependencyScope 方法中查看相关代码。

在 WebAPI 中您会注意到的一件大事是您实际上不需要在全局静态值中设置任何内容 - 也就是说,您不需要设置全局配置/解析器因为现在一切都是基于实例的。

对于测试,这意味着:

  • 您的设置将使用适当的依赖解析器和配置创建一个 HttpRequestMessage
  • 您的拆卸将处理 HttpRequestMessage,这将依次处理依赖范围等。
  • 个别测试将使用 HttpRequestMessage.GetDependencyScope() 如果他们需要手动解决某些问题并且请求消息将用于协调/传递范围。

以更具体的方式,它可能看起来像:

private HttpRequestMessage _request;

[SetUp]
public void SetUp()
{
var builder = new ContainerBuilder();
// Register stuff.
var container = builder.Build();
var resolver = new AutofacWebApiDependencyResolver(container);

var config = new HttpConfiguration();
config.DependencyResolver = resolver;
config.EnsureInitialized();

this._request = new HttpRequestMessage();
this._request.SetConfiguration(config);
}

[TearDown]
public void TearDown()
{
this._request.Dispose();
}

[Test]
public void Test()
{
// When you need to resolve something, use the request message
this._request.GetDependencyScope().GetService(typeof(TheThing));
}

这样做的好处是您不必在每次测试后都与全局配置设置作斗争或重置静态值。

您可能想知道为什么要传递整个请求消息而不仅仅是依赖项解析器 - 原因是请求消息协调和控制依赖项范围的生命周期。否则,当您多次调用 GetDependencyScope 时,您将获得多个不同的范围,而不是您期望的相同范围。

从设计角度考虑的一些事情:

  • 您可能希望将事物的实际注册放入 Autofac 模块,以便它可以在测试和您的 RegisterAndSetResolver 方法中重复使用,而不必担心全局静力学被篡改。
  • 而不是 RegisterAndSetResolver 修改全局静态配置,您可以考虑只在 HttpConfiguration 对象上设置解析器,该对象连接在 WebAPI 为您提供的 WebApiConfig.Register 方法。将 HttpConfiguration 对象作为参数,并将解析器设置在该对象上而不是全局对象上。
  • 如果您在单元测试中对所有内容进行每次注册,您的单元测试可能更接近于“集成测试”。您可能会考虑仅查看您正在测试的内容所需的内容,并使用模拟框架来注册 stub ,而不是实际注册大量“真实内容”。

无论如何,HttpRequestMessage 是用于 WebAPI 的方法。

关于c# - 从 MVC 的 DependencyResolver 过渡到 AutofacWebApiDependencyResolver - .Current 在哪里?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22331095/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com