温莎短暂的生活方式

时间:2012-08-13 14:54:28

标签: asp.net-mvc-3 model-view-controller castle-windsor

我的温莎容器中有一些非常奇怪的行为。

我已经像这样配置了我的容器。

Container = new WindsorContainer();
Container.Kernel.ComponentModelCreated += KernelComponentModelCreated;
Container.Install(FromAssembly.This());

private static void KernelComponentModelCreated(ComponentModel model)
{
    if (model.LifestyleType == LifestyleType.Undefined)
        model.LifestyleType = LifestyleType.Transient;
}

所以我假设我没有指明生活方式的所有组件会得到一种短暂的生活方式,它似乎直到现在都没有给出任何问题。

我启动了多个异步任务,它们都解析了一些组件。 (所以你希望每个任务都获得一个新的组件实例)

但是现在我知道任务没有获得新实例,因为我的任务因组件的交叉线程问题而失败。 (因此它被用于多个任务中)

当我替换Container.Resolve(somecomponent);只需创建新组件就可以了。

var contextProvider = MvcApplication.Container.Resolve<IDbContextProvider>();

替换为

var contextProvider = new DbContextProvider();

所以我的问题是我在这里错过了什么。

由于显式配置,任务在瞬态配置的MVC3控制器中启动。

由于上述代码,DbContextProvider在所有配置为瞬态的存储库中得到解析。

我在文档中发现的另一件事是。您必须释放瞬态组件。我使用IDisposable实现了所有组件。但是由于我的控制器中的自动构造器注入,我不能完全确定是否必须手动释放它们,如果是这样,我该怎么做呢。 (是的,我知道我必须在容器上调用Release方法)

更新

以下代码负责释放和解析我的控制器:

public class WindsorControllerFactory : DefaultControllerFactory
{
    private readonly IKernel _kernel;

    public WindsorControllerFactory(IKernel kernel)
    {
        _kernel = kernel;
    }

    public override void ReleaseController(IController controller)
    {
        _kernel.ReleaseComponent(controller);
    }

    protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
    {
        if (controllerType == null)
        {
            throw new HttpException(404, string.Format("The controller for path '{0}' could not be found.", requestContext.HttpContext.Request.Path));
        }
        return (IController)_kernel.Resolve(controllerType);
    }
}

是否有一些示例可用于测试是否所有依赖项都以它们的方式解析和释放? (LifeStyle测试)

1 个答案:

答案 0 :(得分:1)

我不确定这是否是导致您出现问题的原因,但您应该仅在ComponentModel的实施中修改IContributeComponentModelConstruction

查看documentation of the component model construction contributors以获取有关如何有效更改容器默认生活方式的帮助。

关于IDisposable s的处理 - 如果您释放控制器,那么一切都将与Windsor一起使用:)