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"));

此代码的工作原理是 TorDependency 当前是字符串类型,并且两个参数也是字符串。

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;
}

编辑二重奏:

好的,所以您希望能够为密钥传递任何数据类型。这更接近你需要的吗?您可以通过名称获取方法,然后通过调用将其转换为封闭的泛型MakeGenericMethod。然后你调用它。

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