首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用WebApi、SimpleInjector和MediatR时正确设置范围

使用WebApi、SimpleInjector和MediatR时正确设置范围
EN

Stack Overflow用户
提问于 2016-09-22 14:40:02
回答 2查看 1.5K关注 0票数 0

控制器

代码语言:javascript
运行
复制
public class LocationsController : ApiController
{
    private readonly IMediator _mediator;

    public LocationsController(IMediator mediator)
    {
        _mediator = mediator;
    }

    public IEnumerable<Place> Get()
    {
        return _mediator.Send(new GetLatestMapData<Place>());
    }
}

在Get()操作的第一个请求中,SimpleInjector实例化了该处理程序并正确地执行了它。

对于第二个请求(例如,浏览器中的F5),它在以下方面失败:

没有为类型为.的请求找到处理程序。 容器或服务定位器没有正确配置,或者处理程序没有在容器中注册。

和内部例外:

无法访问已释放的对象。 对象名称:“ThreadLocal对象已被处理。”

OWIN启动

代码语言:javascript
运行
复制
public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        // SimpleInjector
        var container = CompositionRoot.CreateContainer();

        var config = GlobalConfiguration.Configuration;

        config.DependencyResolver = new SimpleInjectorWebApiDependencyResolver(container);

        // Routing
        config.MapHttpAttributeRoutes();

        config.Routes.MapHttpRoute("DefaultApi", "api/{controller}/{id}",
            new { id = RouteParameter.Optional });

        config.EnsureInitialized();

        app.UseWebApi(config);
    }
}

SimpleInjector IPackage for WebAPI project

代码语言:javascript
运行
复制
public class Installer : IPackage
{
    public void RegisterServices(Container c)
    {
        c.Options.DefaultScopedLifestyle = new WebApiRequestLifestyle();

        c.RegisterWebApiControllers(GlobalConfiguration.Configuration);
    }
}

我认为所发生的事情是正确地创建了Handler,然后在第一个请求之后进行处理。现在,我不知道为什么,但是在随后的请求中,Handler没有被重新创建。我知道这一点,因为如果我将WebApiRequestLifestyle更改为“作用域结束时不释放”,则它适用于每个请求:

代码语言:javascript
运行
复制
c.Options.DefaultScopedLifestyle = new WebApiRequestLifestyle(false
/*disposeInstanceWhenScopeEnds*/);

问题

  1. 我是否应该将disposeInstanceWhenScopeEnds参数设置为false?
  2. 如果没有,正确的解决办法是什么?
  3. 我看这是通过创建一个LifetimeScopeDecorator解决之前..。但是,这个功能肯定已经由SimpleInjector WebApi集成库提供了吗?我遗漏了什么?

(谢谢你的阅读)

EN

回答 2

Stack Overflow用户

发布于 2016-09-22 15:08:03

这个链接提供了关于依赖性解析和使用IDependencyResolver / IDependencyScope接口的良好指导。

你马上就会发现,他们接触到的生命跨度往往会变得有点棘手。

本节特别有趣:

依赖范围与控制器寿命 控制器是根据请求创建的。为了管理对象的生存期,IDependencyResolver使用了作用域的概念。 附加到HttpConfiguration对象的依赖解析器具有全局范围。当Web创建控制器时,它调用BeginScope。此方法返回表示子范围的IDependencyScope。 然后,Web在子作用域中调用GetService来创建控制器。当请求完成时,Web调用Dispose在子作用域中。使用Dispose方法处理控制器的依赖项。

按照惯例,引导服务在应用程序启动过程中只会发生一次,并且您知道,在那个时候解决任何依赖关系。只有当工作进程关闭时(例如,没有活动),才会调用dispose。

通常,我认为已解决的实例在生命周期中保留是非常正常的,除非它们在使用后必须被销毁。但是,给出的示例说明,一旦请求完成,我们必须正确地处理。因此,我建议您使用提供的示例作为指导正确地处理实例。

在使用IoC和WebApi时,这对我有帮助。我希望这能帮到你!

票数 0
EN

Stack Overflow用户

发布于 2016-09-27 13:45:14

你需要安排你的生命周期范围

代码:

代码语言:javascript
运行
复制
container.Options.DefaultScopedLifestyle = new WebApiRequestLifestyle();

container.Options.LifestyleSelectionBehavior = new WebApiInjectionLifestyle();


internal class WebApiInjectionLifestyle : ILifestyleSelectionBehavior
{
    public Lifestyle SelectLifestyle(Type serviceType, Type implementationType)
    {
        return Lifestyle.Scoped;
    }
}

更详细

https://simpleinjector.readthedocs.io/en/latest/lifetimes.html

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39642121

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档