StructureMap 3获取请求的类型

时间:2014-09-30 04:31:45

标签: structuremap structuremap3

我有以下在版本2.6.4中工作的StructureMap注册,并且我最终升级到最新的SM(截至本文撰写时为3.1.2)。并且需要更新它,因为它似乎不再是IContext.BuildStack。

以下是2.6.4的旧版工作:

        initialization.For(typeof(IRepository<,>))
                             .Use(context =>
                             {
                                 var genericArgs = context.BuildStack.Current.RequestedType.GetGenericArguments();

                                 return RepositoryFactory.GetInstance(genericArgs[0], genericArgs[1], repositoryName);
                             }
            );

所以我认为将其更改为可行:

        initialization.For(typeof (IRepository<,>))
            .Use("IRepository<,>", context =>
                                   {
                                       var genericArgs = context.ParentType.GetGenericArguments();

                                       return RepositoryFactory.GetInstance(genericArgs[0], genericArgs[1],
                                           repositoryName);
                                   }
            );

但context.ParentType为null。当我查看context.RootType时,它被设置为System.Object,这显然不是我想要的。

我获取此存储库实例的测试代码是:

var userRepository = ObjectFactory.GetInstance<IRepository<User, Guid>>();

我没有看到任何有此信息的其他财产,但我猜我错过了什么。

2 个答案:

答案 0 :(得分:6)

你没有遗漏任何东西。在GitHub上有人发布了一个类似的问题:https://github.com/structuremap/structuremap/issues/288。 结构图的作者杰里米米勒回应道:

  

它必须是新的发展。它必须有一个3.2版本。

建议的解决方法是创建自定义实例并覆盖ClosingType方法。您可以按如下方式执行此操作:

public class CustomInstance : Instance
{
    public override IDependencySource ToDependencySource(Type pluginType)
    {
        throw new NotImplementedException();
    }

    public override Instance CloseType(Type[] types)
    {
        var repository = RepositoryFactory.GetInstance(types[0], types[1], repositoryName);                                                           
        return new ObjectInstance(repository);
    }

    public override string Description
    {
        get { throw new NotImplementedException(); }
    }

    public override Type ReturnedType
    {
        get { return typeof (IRepository<,>); }
    }
}

现在,您只需要将开放泛型类型连接到结束类型,如下所示:

initialization.For(typeof (IRepository<,>)).Use(new CustomInstance());

答案 1 :(得分:4)

我根据您的问题在此场景的StructureMap 3代码库中添加了一个新示例:

https://github.com/structuremap/structuremap/blob/master/src/StructureMap.Testing/Acceptance/builder_for_open_generic_type.cs

我不得不问,如果您使用IoC容器,RepositoryBuilder之类的目的是什么?

无论如何,这种实现应该比旧的反射方法更有效。