1

私は現在、StructureMap の上にある IoC コンテナーの抽象化に取り組んでいます。アイデアは、他の IoC コンテナーでも機能する可能性があるということです。

public interface IRegister
{
    IRegister RegisterType(Type serviceType, Type implementationType, params Argument[] arguments);
}

public abstract class ContainerBase : IRegister
{
    public abstract IRegister RegisterType(Type serviceType, Type implementationType, params Argument[] arguments);
}

public class StructureMapContainer : ContainerBase
{
    public StructureMapContainer(IContainer container)
    {
        Container = container;
    }

    public IContainer Container { get; private set; }

    public override IRegister RegisterType(Type serviceType, Type implementationType, params Argument[] arguments)
    {
        // StructureMap specific code
        Container.Configure(x =>
        {
            var instance = x.For(serviceType).Use(implementationType);
            arguments.ForEach(a => instance.CtorDependency<string>(a.Name).Is(a.Value));
        });

        return this;
    }
}

public class Argument
{       
    public Argument(string name, string value)
    {
        Name = name;
        Value = value;
    }

    public string Name { get; private set; }
    public string Value { get; private set; }
}

次のようにして、このコードを実行できます。

//IContainer is a StructureMap type
IContainer container = new Container(); 
StructureMapContainer sm = new StructureMapContainer(container);

sm.RegisterType(typeof(IRepository), typeof(Repository));

コンストラクターの引数を渡そうとすると問題が発生します。StructureMap を使用すると、必要な数の CtorDependency 呼び出しを流暢に連鎖させることができますが、コンストラクター パラメーターの名前、値、および型が必要です。だから私はこのようなことができます:

sm.RegisterType(typeof(IRepository), typeof(Repository), new Argument("connectionString", "myConnection"), new Argument("timeOut", "360"));

CtorDependency は現在文字列型であり、両方の引数も文字列であるため、このコードは機能します。

instance.CtorDependency<string>(a.Name).Is(a.Value)

このメソッドに任意の型の複数のコンストラクター引数を渡すにはどうすればよいですか? 出来ますか?どんな助けでも大歓迎です。

4

1 に答える 1

2

動的な匿名オブジェクトを使用して、引数を渡すことができます。次に、リフレクションを使用してプロパティを調べます。値は任意の型にすることができます。

dynamic example = new
{
    a = 3,
    b = "hello"
};

foreach (PropertyInfo p in example.GetType().GetProperties())
{
    string key = p.Name;
    dynamic value = p.GetValue(example, null);
    Console.WriteLine("{0}: {1}", key, value);
}

これは出力します

a: 3
b: こんにちは

必要に応じて変更してください。

編集:

これだけは明らかです。登録メソッドは動的パラメーターを取ります。このようなものになります。私は StructureMap を持っていませんが、これで正しい方向に進むはずです。

public override IRegister RegisterType(Type serviceType, Type implementationType, dynamic arguments)
{
    // StructureMap specific code
    Container.Configure(x =>
    {
        var instance = x.For(serviceType).Use(implementationType);
        foreach (PropertyInfo p in arguments.GetType().GetProperties())
        {
            string key = p.Name;
            object value = p.GetValue(arguments, null);
            instance.CtorDependency<string>(key).Is(value));
        }
     });

    return this;
}

Part Deux の編集:

さて、キーの任意のデータ型を渡すことができるようにしたいと考えています。これはあなたが必要としているものに近いですか?メソッドを名前で取得し、 を呼び出してクローズ ジェネリックに変換しMakeGenericMethodます。次に、それを呼び出します。

var method = instance
    .GetType()
    .GetMethod("CtorDependency")
    .MakeGenericMethod(new Type[] { key.GetType() });
method.Invoke(instance, new object[] { key });
于 2013-06-07T15:41:23.493 に答える