代码之家  ›  专栏  ›  技术社区  ›  Michael Stum

有没有从字符串转换为构造函数类型的DI框架?

  •  2
  • Michael Stum  · 技术社区  · 15 年前

    我只是想知道.NET是否有一个DI框架可以为我处理字符串到某种类型的转换?

    基本上我有一个构造函数:

    public MyImplTwo(bool someParam)
    

    以及一个像“真”或“1”这样的字符串。我尝试过Unity,但这会引发一个错误,说明不存在签名为MyImplTwo(字符串)的构造函数:

    container.RegisterType<MyImplBase, MyImplTwo>(new InjectionConstructor(new object[] {"true"}));
    

    有吗?实际上,我主要需要一个围绕activator.createInstance的包装器,所以我在寻找最简单的有效的IOC。另一方面,我不介意“大”容器的额外功能,只要上述功能正常。

    编辑: 我也可以得到作为字符串的所需类型,如果需要,还可以得到参数名。我不能做的事情是a)有一个特定于容器的配置文件(配置是通过数据库完成的)和b)用我不控制的任何属性来修饰那些应该解析的类。

    2 回复  |  直到 15 年前
        1
  •  2
  •   Krzysztof Kozmic    15 年前

    根据你问题中的编辑,我想说 Castle Windsor 应该能够满足你的需求。

    使用温莎的XML配置,可以指定基本参数值,例如

    <component id="myImp"
               service="MyImplBase, MyAssembly"
               type="MyImplTwo, MyOtherAssembly">
        <parameters>
            <someParam>true</someParam>
        </parameters>
    </component>
    

    温莎不要求您将XML配置放入应用程序配置文件中。你可以 从任何XML流读取它 ,包括来自数据库的。下面是一段代码片段,演示如何从XML字符串中读取XML配置:

    string myXml = // read XML from a custom resource...
    
    var container = new WindsorContainer();
    container.Install(
        new ConfigurationInstaller(
            new XmlInterpreter(
                new StaticContentResource(myXml))));
    

    您现在可以使用 container 解决 MyImplBase 它将返回 MyImplTwo 具有 someParam 设置为 true .

    也有温莎 you can pass dependencies as strings to the fluent registration API ,温莎的转换子系统将为您转换它们,这完全不需要任何形式的XML配置。

        2
  •  1
  •   Matthew King    15 年前

    据我所知,System.Boolean没有允许用Activator.CreateInstance实例化它的构造函数。您可能需要使用boolean.parse()或boolean.typarse()。

    我不知道有什么IO框架可以满足您的需要,但是您是否可以使用您喜欢的框架,比如……(使用) Autofac 例如:

    ContainerBuilder builder = new ContainerBuilder();
    builder.RegisterType<MyImplTwo>()
        .As<MyImplBase>()
        .WithParameter("someParam", Boolean.Parse(yourStringHere));
    

    或者,对于可以用Activator.CreateInstance实例化的类型:

    ContainerBuilder builder = new ContainerBuilder();
    builder.RegisterType<MyImplTwo>()
        .As<MyImplBase>()
        .WithParameter("someOtherParam", Activator.CreateInstance(Type.GetType("TypeName"), new object[] { }));
    

    编辑: 另一种选择是扩展您选择的DI框架,并将其与一些字符串序列化功能结合起来。

    例如,使用 AutoFac 具有 Json.NET ,我们可以创建扩展方法:

    static class AutofacExtensions
    {
        public static IRegistrationBuilder<TLimit, TReflectionActivatorData, TStyle>
            WithSerializedParameter<TLimit, TReflectionActivatorData, TStyle>(
                this IRegistrationBuilder<TLimit, TReflectionActivatorData, TStyle> registration, 
                string parameterName, 
                string typeName, 
                string value) 
            where TReflectionActivatorData : ReflectionActivatorData
        {
            return registration.WithParameter(parameterName, JsonConvert.DeserializeObject(value, Type.GetType(typeName)));
        }
    }
    

    并采用如下的扩展方法:

    ContainerBuilder builder = new ContainerBuilder();
    builder.RegisterType<MyImplTwo>()
        .As<MyImplBase>()
        .WithSerializedParameter("someParam", "System.Boolean", "true");
    
    推荐文章