Какие-нибудь DI Frameworks, которые преобразуют из строки в конструктор Типы? - PullRequest
2 голосов
/ 06 июля 2010

Мне просто интересно, есть ли DI Framework для .net, который обрабатывает преобразование типа строка-в-меня?

В основном у меня есть этот конструктор:

public MyImplTwo(bool someParam)

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

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

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

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

Ответы [ 2 ]

2 голосов
/ 07 июля 2010

Исходя из редактирования вашего вопроса, я бы сказал, Замок Виндзор должен быть в состоянии удовлетворить ваши потребности.

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

1 голос
/ 07 июля 2010

Насколько мне известно, 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[] { }));

Редактировать: еще один вариант - расширить структуру 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");
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...