StructureMap PerRequest对象注入Singleton内存范围?

时间:2013-10-18 07:45:33

标签: c# dependency-injection inversion-of-control structuremap

我已将2个对象实例配置到structmap

x.ForRequestedType<IStayOnTillAppDies>().TheDefaultIsConcreteType<StayOnTillAppDies>().CacheBy(InstanceScope.Singleton);

x.ForRequestedType<IDiesWhenRequestObjectDies>().TheDefaultIsConcreteType<DiesWhenRequestObjectDies>().CacheBy(InstanceScope.PerRequest);

如您所见,一个是单例/共享范围对象,而另一个是PerRequest。

Singleton对象StayOnTillAppDies将保持活动直到app被杀死,而PerRequest对象DiesWhenRequestObjectDies应该在请求作用域死亡时从内存中清除。

我需要在StayOnTillAppDies中使用对象DiesWhenRequestObjectDies,以便使用Constructor Injection相应地注入它。

public class StayOnTillAppDies : IStayOnTillAppDies 
{
  private readonly IDiesWhenRequestObjectDies   _diesWhenRequestObjectDies;

  public StayOnTillAppDies (IDiesWhenRequestObjectDies diesWhenRequestObjectDies)
  {                       
    _diesWhenRequestObjectDies = diesWhenRequestObjectDies;
  }

  ....
  ....
  ....
}

_diesWhenRequestObjectDies仅在StayOnTillAppDies中的一个或两个位置是必需的,但是这里注入的对象永远不会被释放,因为StayOnTillAppDies是Singleton范围。

我们如何处理这个以确保PerRequest对象仅在请求的时间段内保留并在以后准备好收集?

1 个答案:

答案 0 :(得分:2)

您使用委托注射来解决此问题。

public class StayOnTillAppDies : IStayOnTillAppDies
{
    private readonly Func<IDiesWhenRequestObjectDies> resolver;

    public StayOnTillAppDies(Func<IDiesWhenRequestObjectDies> resolver)
    {
        this.resolver = resolver;
    }
}

当您需要StayOnTillAppDies

的实例时,请在IDiesWhenRequestObjectDies课程中使用以下代码
IDiesWhenRequestObjectDies instance = this.resolver();

这是我用来设置它的配置。

IContainer container = new Container(x =>
    {
        x.ForRequestedType<IStayOnTillAppDies>()
            .TheDefaultIsConcreteType<StayOnTillAppDies>()
            .CacheBy(InstanceScope.Singleton);

        x.ForRequestedType<IDiesWhenRequestObjectDies>()
            .TheDefaultIsConcreteType<DiesWhenRequestObjectDies>()
            .CacheBy(InstanceScope.PerRequest);
    });

container.Configure(x =>
    {
        x.SelectConstructor<StayOnTillAppDies>(() =>
            new StayOnTillAppDies(() => 
                container.GetInstance<IDiesWhenRequestObjectDies>()));
    });