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

时间:2010-07-06 17:00:54

标签: c# .net dependency-injection

我只是想知道是否有针对.net的DI框架为我处理字符串到某种类型的转换?

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

public MyImplTwo(bool someParam)

和一个像“true”或“1”的字符串。我已经尝试过Unity,但是这会抛出一个错误,说没有带有签名MyImplTwo(string)的构造函数存在:

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

有吗?基本上我主要需要一个围绕Activator.CreateInstance的包装器,所以我正在寻找最简单的IoC。另一方面,只要以上工作原理,我就不介意“大”容器的额外功能。

编辑:我也可以将所需类型作为字符串获取,如果需要还可以使用argumentName。我不能做的事情是a)有一个特定于容器的配置文件(配置通过数据库完成)和b)装饰应该用任何属性解析的类,因为我不控制它们。

2 个答案:

答案 0 :(得分:2)

根据您的问题中的修改,我会说Castle Windsor应该能够满足您的需求。

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

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

Windsor不要求您将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

同样使用Windsor you can pass dependencies as strings to the fluent registration API,Windsor中的转换子系统将为您转换它们,这完全消除了对任何形式的XML配置的需求。

答案 1 :(得分:1)

据我所知,System.Boolean没有一个构造函数,可以使用Activator.CreateInstance实例化它。您可能必须使用Boolean.Parse()或Boolean.TryParse()。

我不知道任何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框架,并将其与一些字符串序列化功能相结合。

例如,将AutofacJson.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");