Structuremap PerRequest生命周期

时间:2011-03-29 15:29:08

标签: c# .net structuremap

我希望在请求的生命周期内动态地将一个实例注入到结构图中(即在注册表/配置之外)。

目前我在HandleBeginRequest的{​​{1}}事件中执行此操作:

IHttpModule

但是,如果在应用程序的某些生命中,我会这样做:

container.Configure(x => x.For<IMyClass>()
  .LifecycleIs(Lifecycles.GetLifecycle(InstanceScope.PerRequest))
  .Use(new MyClass()));

我看到ObjectFactory.WhatDoIHave(); 的配置实例数量与已有请求(或至少有大量数据)一样。

考虑到这一点,考虑到我的代码,这种方式是有道理的。

有没有更好的方法将实例注入到容器中,只是为了当前请求的生命周期,不会污染整个容器?<​​/ p>

由于

3 个答案:

答案 0 :(得分:13)

您的问题是,您在每个请求中注册了一次容器类型,这是在注册时产生的。理想情况下,应在应用程序的生命周期中配置容器一次 - 通常在Web应用程序的Application_Start事件中。

Structuremap允许您指定在创建对象时调用的创建函数,这将允许您配置高级对象创建步骤。

而不是在Begin_Request事件中当前调用Configure,而是在Application_Start期间将以下内容粘贴在容器配置中。

For<IMyClass>().HttpContextScoped().Use(() => new MyClass());

注意Use方法中的lambda。 lambda可以包含创建对象所需的任何逻辑,并且每个生命周期将调用一个逻辑(在HttpContext生命周期的情况下,每个请求)。

答案 1 :(得分:6)

我最终选择了这个

For<IRequestContextStorage>()
    .HybridHttpOrThreadLocalScoped()
    .Use<RequestContextStorage>();

For<MyClass>()
    .Use(c => c.GetInstance<IRequestContextStorage>().Get<MyClass>());

...

public class RequestContextStorage : IRequestContextStorage
{
    readonly IDictionary<Type, object> hash;

    public RequestContextStorage()
    {
        this.hash = new Dictionary<Type, object>();
    }

    public T Get<T>() where T : class
    {
        if(this.hash.ContainsKey(typeof(T)))
            return this.hash[typeof (T)] as T;

        return null;
    }

    public void Set<T>(T instance)
    {
        this.hash[typeof (T)] = instance;
    }
}

...


static void HandleBeginRequest(object sender, EventArgs e) {

    ObjectFactory.Get<IRequestContextStore>().Set(new MyClass());

}

答案 2 :(得分:3)

如果您只有一个容器,并且您有多个请求,则会遇到此问题。我建议通过将它们存储在HttpContext.Items中来自己管理每个请求实例。

如果您希望能够通过容器访问它,请创建一个不包含任何状态的网关类,并为您提取HttpContext中的每个请求依赖项。在容器中注册,并将每个请求对象的依赖关系更新为网关。

更新

我不敢相信我之前忽略了这一点,你真正想要的是使用HttpContextLifecycle,它将在HttpContext.Items集合中缓存一个给定的实例,它将在整个请求中可用。在并发请求期间,您仍然会有多个实例处于活动状态,但StructureMap可以根据HttpContext.Current找出要返回的实例。

相关问题