3

我有以下在 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 为空。当我查看 context.RootType 它设置为 System.Object 这显然不是我想要的。

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

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

我没有看到任何其他具有此信息的属性,但我猜我错过了一些东西。

4

2 回答 2

6

你没有错过什么。在 GitHub 上,有人发布了一个类似的问题:https ://github.com/structuremap/structuremap/issues/288 。Structuremap 的作者 Jeremy Miller 回应:

这将必须是新的发展。它必须有 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());
于 2014-10-06T18:44:04.300 回答
4

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

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

不过,我不得不问,RepositoryBuilder如果您使用 IoC 容器,这样做的目的是什么?

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

于 2014-10-07T12:55:22.177 回答