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、Version = 1.0.0.0、Culture = neutral、publicKeyToken = null \ r \ nパラメータ名:インスタンスのインスタンスを検索しようとしています"}

2番目のコンストラクターを削除し、名前付きインスタンスを取得するだけで、すべてのコードが正しく機能します。

アップデート:

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 で意図的にサポートされていないか、バグです。

しかし、最初に 1 つのエラーがあります。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);
    });
}

犯人はラムダの最初の行です。

if (!plugin.CanBeAutoFilled) return;

これは、コンストラクター (したがって型) を不適格とする行です。文字列を「自動入力」することはできません。新しい文字列を作成することはできず、注入のために登録されないためです。

その行をコメントアウトすると、コードが機能するようになります。私を困惑させているのは、コンストラクターを暗黙的に作成できなかった理由を理解していますが、記述されたコードは、明示的な引数を渡したときにコードが機能しないように見えることです。

StructureMap の経験が豊富な人がより専門的なガイダンスを提供できるかもしれませんが、これが何もないよりはましであることを願っています。

于 2012-10-24T21:29:50.463 に答える