StructureMap获取请求的类型

时间:2010-10-15 16:46:33

标签: structuremap

配置StructureMap容器​​时是否可以将请求类型作为参数传递。

例如:

            container.Configure(x => {
                x.For<ILogger>().Use(new TestLogger(log.Add, requestingType));         
            });

请求类型是消费对象的类型:

public class SomeClass
{
    private readonly ILogger logger;
    public SomeClass(ILogger logger)
    {
        this.logger = logger;
    }
}

因此传递给记录器的类型是SomeNamespace.SomeClass。

谢谢, 本

3 个答案:

答案 0 :(得分:3)

您可以使用StructureMap的IContext轻松访问所请求的类型。

ObjectFactory.Configure(
    x => {
        x.For<ILogger>().Use( context => new TestLogger( context.ParentType ) );
    } );

在上面的语句中,context.ParentType返回StructureMap创建的类型。

Jeremy Miller也在博文中介绍了这个话题。本文使用过时的语法,但它仍然相关:http://codebetter.com/jeremymiller/2009/01/15/using-the-build-session-in-structuremap/

如果要检查IContext中的所有可用属性,可以使用匿名函数并在返回行上设置断点,如下所示:

ObjectFactory.Configure(
    x => {
        x.For<ILogger>()
                .Use( context =>
                {
                    // Set breakpoint here and inspect the context
                    return new TestLogger( context.ParentType );
                } );
    } );

<强>更新

确保使用.AlwaysUnique()(相当于.CacheBy(InstanceScope.Unique)的旧语法),否则StructureMap将缓存ILogger的第一个请求,这将导致原始记录器被注入到所有后续在单个GetInstance()调用期间请求ILogger。

如果你有嵌套类,每个都需要一个ILogger,那么这很容易发生,所以请求ObjectFactory.GetInstance&lt; ISomeClass&gt;()将导致为层次结构中最深的类创建ILogger,然后所有其他类将接收ILogger的相同实例,这很可能是您想要发生的事情。

因此,考虑到此更新和Ben的提示,这是一个更好的解决方案:

x.For<ILogger>()
    .AlwaysUnique()
    .Use( c => new TestLogger( c.ParentType ?? c.BuildStack.Current.ConcreteType ) );

答案 1 :(得分:0)

我找到了解决方案here

基本上我们将ILogger接口更改为ILogger<T>并使用了StructureMap中的泛型类型推理功能。

严格地说,这不能回答我是否可以获得请求类型的问题,所以如果你知道如何做到这一点请回复 - 知道这将是有用的。

答案 2 :(得分:0)

首先,我想指出一个潜在的问题,使用Use(new Type())注册一个实例会导致该实例被注册为单例。为避免这种情况,您可以使用(()=&gt; new Type())。

以下是在配置时获取所请求类型的方法:

container.Configure(x => {
  x.For<ILogger>().Use(c => new TestLogger(log.Add, c.Root.RequestedType));
});