Structuremap PerRequest生命周期

And*_*ock 5 .net c# structuremap

我想在运行中(即在注册表/配置之外)将一个实例注入到结构映射中,该实例在请求的生命周期中存在.

目前我在做这个HandleBeginRequest的事件IHttpModule:

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

但是,如果在应用程序的生命中的某个时刻我做了:

ObjectFactory.WhatDoIHave();
Run Code Online (Sandbox Code Playgroud)

我看到尽可能多的已配置实例IMyClass(或至少有大量数据).

考虑到它,考虑到我的代码,这种方式是有意义的.

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

谢谢

PHe*_*erg 13

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

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

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

For<IMyClass>().HttpContextScoped().Use(() => new MyClass());
Run Code Online (Sandbox Code Playgroud)

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


And*_*ock 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());

}
Run Code Online (Sandbox Code Playgroud)