2010-07-06 2 views
2

Мне просто интересно, существует ли DI Framework для .net, который обрабатывает преобразование типа «строка-в-какое-то» для меня?Любые структуры DI, которые преобразуют из строки в конструктор Типы?

В принципе у меня есть этот конструктор:

public MyImplTwo(bool someParam) 

и строка, как "истина" или "1". Я попытался Unity, но выдает ошибку о том, что нет конструктора с подписью MyImplTwo (строка) не существует:

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

Есть один? По сути, мне в основном нужна обертка вокруг Activator.CreateInstance, поэтому я ищу простейший IoC, который работает. С другой стороны, я бы не возражал против дополнительной функциональности «больших» контейнеров, пока это работает.

Редактировать: Я могу получить нужный тип как строку, а также, если требуется, также имя аргумента. То, что я не могу сделать, это a) иметь конфигурационный файл, специфичный для контейнера (конфигурация выполняется через базу данных) и b) украшать классы, которые должны быть разрешены с любыми атрибутами, поскольку я их не контролирую.

+0

Я обновил ответ Марка со ссылкой на документы Виндзора, объяснив, как это сделать без любой формы XML-конфигурации. –

ответ

2

на основе редактирования в вашем вопросе, я 'd say Castle Windsor должен уметь удовлетворить ваши потребности.

Используя конфигурацию XML Windsor, вы можете указать значения примитивных параметров, например.

<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, а подсистема преобразования в Виндзоре будет их конвертировать для вас, что полностью исключает необходимость в любой форме XML-конфигурации.

+1

более точно Windsor имеет подсистему преобразования, которая реализует «ITypeConverter», который делает все это –

1

Насколько мне известно, System.Boolean не имеет конструктора, который позволит ему создавать экземпляр с помощью Activator.CreateInstance. Вам, вероятно, придется использовать Boolean.Parse() или Boolean.TryParse().

Я не знаю ни структур ввода-вывода, которые делают то, что вы хотите, но не могли бы вы, возможно, просто работать с предпочтительной структуры, как так ... (с использованием 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[] { })); 

Edit: Другим вариантом было бы расширить 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"); 
Смежные вопросы