1

我有一个对象:

public class TestEvent : IEvent
{
    private string _id;

    public TestEvent()
    {
    }

    public TestEvent(string eventId)
    {
        _id = eventId;
    }
}

我有一个 StructureMap 注册表:

public class TheRegistry : Registry
{
    public TheRegistry()
    {
        Scan(_ =>
            {
                _.TheCallingAssembly();
                _.AddAllTypesOf<IEvent>().NameBy(t => t.Name.ToUpper());
            });
    }
}

我正在尝试使用 StructureMap 容器获取 IEvent 的命名实例并传入“eventId”的构造函数参数:

var id = "TESTEVENT";
var args = new ExplicitArguments();
args.SetArg("eventId", id);
var eventInstance = _container.GetInstance<IEvent>(args, id);

认为文档建议它应该可以工作,但是我收到了 ArgumentNullException:

{"正在尝试查找 MyProject.IEvent 类型的实例,MyProject,版本=1.0.0.0,文化=中性,publicKeyToken=null\r\n参数名称:实例"}

如果我删除第二个构造函数,所有代码都可以正常工作,并且只获取命名实例。

更新:

在 Kirk 的调查之后,我已经能够通过创建一个简单的对象来保存任何所需的参数来解决这个“问题”。现在可以了。

public class EventArguments
{
    public string EventId { get; set; }
}

...

var eventName = Context.Parameters.EventTypeName.ToString().ToUpper();
var args = new ExplicitArguments();
args.SetArg("args", new EventArguments { EventId = eventName });
var eventInstance = _container.GetInstance<IEvent>(args, eventName);
4

1 回答 1

1

全面披露:我以前从未使用过 StructureMap,所以我可能会误解它的用途。但据我所知,StructureMap 故意不支持这个用例,或者它是一个错误。

但首先,你有一个错误;您需要修复您的电话id以匹配您的.ToUpper电话(即应该是var id = "TESTEVENT";,不是var id = "TestEvent";)。

但是,一旦你这样做了,它仍然不起作用。检查源代码,很清楚为什么。检查类型的构造函数(在本例中为TestEvent),如果任何构造函数声明了类型为“简单”的参数(即原语、字符串等),则该构造函数将被断然取消参与该.GetInstance行为的资格。

具体来说,如果您检查StructureMap.Graph.PluginFamily.discoverImplicitInstances()

private void discoverImplicitInstances()
{
    _pluggedTypes.Each((key, plugin) =>
    {
        if (!plugin.CanBeAutoFilled) return;

        if (hasInstanceWithPluggedType(plugin)) return;

        ConfiguredInstance instance = new ConfiguredInstance(plugin.PluggedType).WithName(key);
        FillInstance(instance);
    });
}

罪魁祸首是 lambda 中的第一行:

if (!plugin.CanBeAutoFilled) return;

那是取消您的构造函数(以及您的类型)资格的行。字符串不能“自动填充”,因为您不能只新建一个,并且它们不会被注册用于注入。

如果你注释掉那一行,你的代码现在就可以工作了。让我感到困惑的是,虽然我理解为什么不能隐式创建您的构造函数,但当您传递显式参数时,编写的代码似乎也使代码无法工作。

也许对 StructureMap 有更多经验的人能够提供更多的专家指导,但希望这总比没有好。

于 2012-10-24T21:29:50.463 回答